在 C89 和 C++ 中用空参数调用宏真的是未定义的行为吗?

Is it really undefined behavior to call macro with empty arguments in C89 & C++?

考虑以下程序:

#include <iostream>
#define add(s,m,a)  ( s + m + a + 0 )
int main()
{
    std::cout<<add(3,4,5)<<'\n';
    std::cout<<add(15,30,)<<'\n';
    std::cout<<add(10, , 33)<<'\n';
    std::cout<<add(10,,)<<'\n';
    std::cout<<add(,,)<<'\n';   
}

我的编译器 gcc 4.8.1 给出以下警告:

6   23 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

7   25 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

8   21 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

8   21 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

9   19 [Warning] invoking macro add argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

9   19 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

9   19 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default]

我知道 C++ 不支持空预处理器函数宏参数。但是 C99 允许使用空(缺失)参数指定预处理器函数宏。

(此功能可能作为许多 C++ 编译器的扩展提供,例如上述情况中的 g++)。根据 C89 和 C++ 标准,程序的行为确实未定义吗?

C89/C90 和 C++98 标准根本没有定义应如何处理空宏参数。因此,行为因疏忽而未定义,预处理时警告或错误消息是合理的结果。

正如您所指出的,C99 是第一个允许它的 C 标准,但同样值得一提的是 C++11 采用了 C99 措辞。所以不,它不再是 C++ 中具有空宏参数的未定义行为。