4

次のコードを考えてみましょう(実際の例) :

#define TEST_VA(mX, ...) TEST
#define STRINGIFY_IMPL(mX) #mX
#define STRINGIFY(mX) STRINGIFY_IMPL(mX)

#include <iostream>

int main()
{
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
    std::cout << STRINGIFY(TEST_VA()) << std::endl;
    return 0;
}

clang++ 3.4は文句を言います:

main.cpp:9:37: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
                                    ^
main.cpp:1:9: note: macro 'TEST_VA' defined here
#define TEST_VA(mX, ...) TEST
        ^
main.cpp:10:33: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
        std::cout << STRINGIFY(TEST_VA()) << std::endl;
                                       ^
main.cpp:1:9: note: macro 'TEST_VA' defined here
#define TEST_VA(mX, ...) TEST

プロジェクトのサンプル コードのように、いくつかの可変長マクロを使用します。

...可変個引数マクロのパラメーターに引数を渡さないのは安全ですか? (基本的に警告無視)

それとも問題を引き起こす可能性がありますか?

標準で明示的に禁止されていますか?

4

2 に答える 2

2

標準では技術的に禁止されています。C++11 §16.3/4 から (強調を追加):

マクロ定義の識別子リストが省略記号で終わらない場合、関数のようなマクロの呼び出しにおける引数の数 (前処理トークンを含まない引数を含む) は、マクロ定義のパラメーターの数と等しくなければなりません。それ以外の場合、呼び出しには、マクロ定義のパラメーターよりも多くの引数が必要です ( を除く...))呼び出しを終了する前処理トークンが存在する必要があります。

一部のコンパイラはこれを拡張として許可する場合がありますが、標準に準拠したコードが必要な場合は、可変引数マクロの省略記号パラメーターに少なくとも 1 つの引数を常に含める必要があります。

于 2014-01-21T18:57:53.370 に答える
1

C++20 以降では、可変引数マクロ パラメーターにゼロ引数を渡すことが許可されていますが、Clang (少なくとも Clang 12) はこの変更をまだ尊重していません。

したがって、C++20 以降をターゲットにして を使用している-pedantic-errors場合は、-Wno-gnu-zero-variadic-macro-argumentsをお勧めします。


[cpp.replace.general]/5

... 呼び出しには、少なくともマクロ定義のパラメーターと同じ数の引数が必要です ( を除く...)。

于 2021-08-19T20:07:51.583 に答える