2

文字列化演算子を使用して、マクロに渡されたコンマを含む可能性のあるパラメーターを文字列に変換しています。私が知っているように、一部の文字は文字列化できません。特に、コンマ (,) はパラメーターを区切るために使用され、右括弧 ()) はパラメーターの終わりを示すために使用されます。そこで、可変長マクロを使用して、次のようにカンマを文字列化演算子に渡します。

#include <stdio.h>

#define TEST 10, 20

#define MAKE_STRING(...)  #__VA_ARGS__
#define STRING(x)       MAKE_STRING(x)

int main()
{
    printf("%s\n", STRING(TEST) );
    return 0;
}

それは正常に動作します。しかし、可変引数マクロがないとどうなるかが思い浮かんだので、マクロを変更します: #define MAKE_STRING(x) #x. これは、Visual C++ 2008/2010 で予期せず正常にコンパイルされ、10, 20gcc/clang が期待どおりにコンパイル エラーを出力している間に出力されます。

マクロ "MAKE_STRING" は 2 つの引数を渡しましたが、1 つしか取りません

だから私の質問: Visual c++ は追加の作業を行っていますか、それとも動作は未定義ですか?

4

3 に答える 3

1

一般に、VS はマクロで追加のパラメーターを許可し、それらを黙ってドロップし STRING(10, 20, 30)ます10。ここではそうではありませんが、VS には gcc がスローしたエラーさえないことを意味します。

追加作業ではなく、「単なる」置換順序の違いです。

于 2014-03-24T13:23:53.800 に答える
-2

なぜこれに賛成票が投じられたのか、または回答が反対票を投じられたのかはわかりません(したがって、投稿者はそれを削除しました)が、あなたが何を期待しているのかわかりません!

#__VA_ARGS__意味がありません。MACRO(a,b,c) があるとします。"a,b,c" を文字列として使用しますか?

http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros

読んでください、それは標準的な動作になりました。マクロの可変長引数は、関数の可変長引数で行うことを許可します。プリプロセッサはテキストで動作します!

関連する唯一の特殊なケースは ## です。これは、余分な引数がない場合に#前のコンマを削除します(したがって、構文エラーを防ぎます)。##

ノート:

その部分を読むことは本当に重要です。MACRO(a,b,c)文字列「a、b、c」は何だと思いますか? または、文字列「a、b、c」が必要な場合は「a、b、c」 文字列「a、b、c」を書きます

#演算子の使用は、次のようなものに最適です

#define REGISTER_THING(THING) core_of_program.register_thing(THING); printf("%s registered\n",#THING);
于 2014-03-24T11:50:31.543 に答える