2017-08-08 97 views
0

我一直在考慮定義以下宏庫:如何使用另一個宏創建C宏名稱?

#define FOO_0(A, B) (A + B) 
#define FOO_1(A, B) (A - B) 

現在我想創建一個新的宏MY_FOO,需要一個第三個參數x,並用它構建宏的名字叫(如FOO_<x>

這裏是我的實驗:

#define MY_FOO(X, A, B) FOO_## X ##(A, B) 

然而,當我嘗試在我的代碼使用它:

int main(void) { 
    int a = 2, b = 3, x = 0; 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
    return 0; 
} 

我得到以下錯誤:

prog.c: In function ‘main’: 
prog.c:6:25: error: pasting "FOO_x" and "(" does not give a valid preprocessing token 
#define MY_FOO(X, A, B) FOO_## X ##(A, B) 
         ^
prog.c:11:41: note: in expansion of macro ‘MY_FOO’ 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
             ^~~~~~ 
prog.c:6:25: warning: implicit declaration of function ‘FOO_x’ [-Wimplicit-function-declaration] 
#define MY_FOO(X, A, B) FOO_## X ##(A, B) 
         ^
prog.c:11:41: note: in expansion of macro ‘MY_FOO’ 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
             ^~~~~~ 

有沒有辦法來解決這個?

+1

第二個##不是必需的。 –

+1

在C中,永遠不需要創建具有完全變量名稱的宏。宏名稱是爲程序員而不是程序。如果你仍然想出這樣的需求,你應該運行一個生成C代碼的外部腳本。 – Lundin

+0

在下面的帖子中自動生成@bipll提出的代碼實際上可能是一個非常好的主意,因爲我必須對很多宏使用相同的模式 – Muffo

回答

3

如果你真的需要把運行時間值到宏名,你必須做你自己:

switch(x) { 
    case 0: printf("FOO_0(%d, %d) = %d", a, b, FOO_0(a, b)); 
      break; 
} 

你甚至可以讓它稍微當地語法DEFS先進:

switch(x) { 
#define CASE(x) case x: printf("FOO_" #x "(%d, %d) = %d", a, b, FOO_ ## x(a, b)); \ 
         break 
    CASE(0); 
#undef CASE 
} 
+0

感謝您的答案!運行時間和編譯時間值之間的區別可能是這個問題的關鍵。 – Muffo

+1

除此之外,宏在編譯本身之前是解析時間值。 :) – bipll