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(强调添加):

如果宏定义中的标识符列表不以省略号结尾,则调用类函数宏时的参数数量(包括那些不包含预处理标记的参数)应等于宏定义中的参数数量。否则,调用中的参数应多于宏定义中的参数(不包括...。应该存在)终止调用的预处理令牌。

一些编译器可能允许将此作为​​扩展,但如果您想要符合标准的代码,则应确保始终为可变参数宏的省略号参数包含至少一个参数。

于 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 回答