受け取る引数に応じて異なるものに展開するCプリプロセッサマクロを書く方法はありますか?Cマクロ内にプリプロセッサを条件付きで置くことはできますか?
#define foo() ???
/* 1 */
foo(name)
/* 2 */
foo(_)
望ましい結果:
/* 1 */
int name;
/* 2 */
/*ignore*/
はい、私はマクロが悪知っています。私はこれを主に好奇心から求めています。
受け取る引数に応じて異なるものに展開するCプリプロセッサマクロを書く方法はありますか?Cマクロ内にプリプロセッサを条件付きで置くことはできますか?
#define foo() ???
/* 1 */
foo(name)
/* 2 */
foo(_)
望ましい結果:
/* 1 */
int name;
/* 2 */
/*ignore*/
はい、私はマクロが悪知っています。私はこれを主に好奇心から求めています。
おそらく多段階マクロ展開を試してみてください。これはBoost preprocessor/control/if libraryによって使用される戦略です。
#define FOO_NAME 1
#define FOO__ 2
#define CONC(a,b) a##_##b
#define FOO(x) CONC(FOO,x)
Cマクロ展開で条件を確認する方法がないと思います。
私が思いつくのは、#
文字列演算子を使用してマクロ引数を文字列リテラルに変換し、実行時関数を使用してチェックすることです。 (あなたは出力変数宣言したいところ。これは、しかし、あなたのケースでは動作しません。)
をたとえば、以下の版画「011」:
#define FOO(x) (strcmp("NAME", #x) ? 1 : 0)
main()
{
printf("%d", FOO(NAME));
printf("%d", FOO(1));
printf("%d", FOO(2));
}
は、コンパイラは、おそらくstrcmp
比較を最適化しますコンパイル時には、本物のプリプロセッサ条件が利用可能であった場合よりも効率的ではありません。しかし、FOO
を通常の関数にすると、より効率的になり、おそらく効率的になります。
#define FOO_name 1
#define FOO__ 0
#define CONC(a,b) a##_##b
#define IF(c, t, e) CONC(IF, c)(t, e)
#define IF_0(t, e) e
#define IF_1(t, e) t
#define FOO(x) IF(CONC(FOO,x), int x;,)
FOO(name) // -> int name;
FOO(_) // -> /*nothing*/
あなたは冒険を感じている場合は、簡単になど、マクロ展開を抑制する、コンマを許可するようにIF
を拡張することができます、ギャビン・スミスの答えに展開するには、あなたが実際にマクロ展開内の状態を確認することができ
ヘルパーマクロ。
上記のように、必要な名前はすべて事前に知っている必要がありますが、
マクロは素晴らしいです。 –
目的を説明したり、より良い例を挙げたりできますか?パラメータはコンパイル時に固定する必要があります。つまり、2つの異なるマクロ名を使用することもできます。 – lurker
@mbratch:この特定のケースでは、マクロを使用して変数のセットを定義していますが、いくつかの変数はオプションであり、定義しないでください。 2つの変数名を使うと、 'foo(a、b)'、 'foo(a、_)'、 'foo(_、b)'と ' foo(_、_) 'となります。 – hugomg