9

私はこのスニペットを見ました:

#define kthread_create(threadfn, data, namefmt, arg...) \
    kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
  1. ##の略ですか?
  2. ##マクロの外に現れるときの意味は何ですか?
4

2 に答える 2

10

他の答えとは反対に、これは実際にはGCC拡張です。変数引数を直接貼り付ける場合、余分な引数が渡されないと問題が発生します。したがって、GCCは、またはvarargs変数(で宣言)とともに##使用すると作成されます。値が含まれている場合は貼り付け、含まれていない場合は前のコンマを削除します。__VA_ARGS__argname...

この拡張機能のドキュメントはこちらです

次に、「##」トークン貼り付け演算子は、コンマと可変引数の間に配置すると特別な意味を持ちます。あなたが書くなら

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

eprintfマクロを使用する場合は、変数引数が省略され、「##」の前のコンマが削除されます。これは、空の引数を渡した場合には発生しません。また、「##」の前のトークンがコンマ以外の場合にも発生しません。

eprintf ("success!\n")
      ==> fprintf(stderr, "success!\n");

上記の説明は、マクロパラメータが可変引数パラメータのみである場合についてはあいまいです。引数が空の引数であるか欠落している引数であるかを区別しようとしても意味がないためです。この場合、C99標準では、コンマを残しておく必要があることは明らかですが、既存のGCC拡張機能を使用してコンマを飲み込んでいます。したがって、CPPは、特定のC標準に準拠している場合はコンマを保持し、それ以外の場合はコンマを削除します。

于 2012-08-21T13:02:13.230 に答える
1

argこれは、マクロ展開に渡されたものをすべて「貼り付け」ます。例:

kthread_create(threadfn, data, namefmt, foo, bar, doo);

に展開:

kthread_create_on_node(threadfn, data, -1, namefmt, foo, bar, doo);
于 2012-08-21T10:50:19.283 に答える