2017-08-08 7 views
0

私は次のマクロを定義するライブラリを与えられている:別のマクロを使ってCマクロ名を作成するには?

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

今、私は三番目の引数xを取り、それが呼ばれるように、マクロの名前を構築する使用新しいマクロMY_FOOを作成したいのですが(例えば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

2番目の '## 'は必須ではありません。 –

+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

関連する問題