在宏参数中使用#line 指令是否合法?

Is it legal to use the #line directive in a macro argument?

我注意到这个程序是用 gcc 编译的:

#define X(A) A

int x = X(
#line 3 "test1.c"
        0
        );

然而,Visual Studio编译失败:

main.cpp
main.cpp(6): error C2121: '#': invalid character: possibly the result of a macro expansion
main.cpp(6): error C2065: 'line': undeclared identifier
main.cpp(6): error C2143: syntax error: missing ';' before 'constant'
main.cpp(6): error C2059: syntax error: 'constant'

我想知道:程序是否合法,或者它是否默默地依赖于恰好使 gcc 接受代码的未定义(或实现定义)行为?

无效。该行为未定义,因此不需要诊断,并且允许实现接受代码。

来自C标准,6.10.3宏替换:

11 [...] If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.

C++ 标准在 16.3 宏替换中包含这些完全相同的词。

如果您编译带有所有警告的示例,gcc 会给您:

warning: embedding a directive within macro arguments is not portable

clang 给你:

warning: embedding a directive within macro arguments has undefined behavior

这对我来说绝对强烈地表明该行为确实是未定义的。