行番号に基づいた名前で関数を作成するCマクロを作成したい。私は次のようなことができると思った(実際の関数は括弧内にステートメントを持っているだろう):
#define UNIQUE static void Unique_##__LINE__(void) {}
私は次のようなものに拡大したいと思っていました:
static void Unique_23(void) {}
それは機能しません。トークンの連結では、位置決めマクロは文字通り処理され、最終的に次のように展開されます。
static void Unique___LINE__(void) {}
これは可能ですか?
(はい、これがどれほど役に立たないとしても、これをやりたい本当の理由があります)。
問題は、マクロの置換がある場合、文字列化演算子#
もトークン貼り付け演算子##
も適用されない場合にのみ、プリプロセッサがマクロを再帰的に展開することです。そのため、いくつかの追加の間接層を使用する必要があります。再帰的に展開された引数でトークン貼り付け演算子を使用できます。
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}
その後、__LINE__
はUNIQUE
の展開中に行番号に展開され(#
または##
のいずれにも関係しないため)、その後トークンの貼り付けが行われますTOKENPASTE
の展開。
同じ行にUNIQUE
マクロの複数のインスタンス化が必要な場合に、評価されるたびに新しい整数に展開される__COUNTER__
マクロも存在することにも注意してください。注:__COUNTER__
は、MS Visual Studio、GCC(V4.3以降)、およびClangでサポートされていますが、標準Cではありません。