・ダーニングのpreprocession、プリプロセッサを使用すると、指定されたトークンにその本体の内側にname
とextra...
の各出現箇所を置き換えると、その本体に__COMMAND_HANDLER(name, extra ...)
マクロのすべての出現を置き換えます。
これは、name
引数に入力するものはすべて関数名になり、extra...
は最初のパラメータ(struct command_invocation *cmd
)の追加パラメータになります。例えば
次の行:前処理後の
__COMMAND_HANDLER(foo, int param) {
/* definition */
}
は次のようになります。
int foo(struct command_invocation *cmd, int param) {
/* definition */
}
一つ重要なことが明らかにされていますextra
前##
とextra...
の代わりを使用して、可変引数(命名...
)は、c標準の一部ではありませんが、GNU extensionsです。コンマの後の##
の効果は、可変引数に何も指定しないようにします。次のようにそれが使われているとき(-pedantic
フラグ付き)GCCとあなたの例をコンパイルすると、あなたは、警告メッセージが表示されます。##
演算子の両側に2つのトークンがある。すなわち
/* The following example will print the following messages:
* warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
* warning: ISO C99 requires at least one argument for the "..." in a variadic
* macro
*/
__COMMAND_HANDLER(bar);
は通常##
は、トークンの連結のための演算子です単一のものに結合される。要するに
#include <stdio.h>
#define FOO(name, number) void name##number()
FOO(bar, 1) { puts("I'm first."); }
FOO(bar, 2) { puts("I'm second."); }
int main() {
bar1();
bar2();
return 0;
}
マクロ定義は標準Cではありません。それはGNU拡張を使用しています。トリプルドットの前にカンマがあり、それが標準マクロだったとします。また、二重アンダースコア(またはアンダースコアと大文字)で始まる名前は、 '実装'によって使用するために予約されています。自分のコードにそのようなマクロを定義するべきではありません。 –