是什么导致在使用包含冒号的类似函数的宏时出现这种编译器差异?

Yor*_*k B 5 c++ gcc clang visual-c++ precompile

A()宏只会在 MSVC 上扩展,而不会在 GCC/Clang 上扩展,除非A()带有前缀,例如Test A().

通过在-E( /E) 标志 ( Godbolt.org )下运行以下代码段:

#define A() HelloWorld::
#define B() ::

A()
B()
Run Code Online (Sandbox Code Playgroud)

我们看到 MSVC 给出了以下输出:

HelloWorld::
::
Run Code Online (Sandbox Code Playgroud)

而 GCC/Clang 给出了不同的输出:

::
Run Code Online (Sandbox Code Playgroud)

但是然后运行这个片段:

#define A() HelloWorld::

A()
Test A()
Run Code Online (Sandbox Code Playgroud)

在所有 3 个编译器上为我们提供以下信息:

HelloWorld::
Test HelloWorld::
Run Code Online (Sandbox Code Playgroud)

为什么 GCC/Clang 输出缺少第一行?为什么它在Test A()写入时正确扩展所有事件?这是在标准中明确定义的,还是特定于编译器的?

wal*_*nut 9

这是 Compiler Explorer (godbolt.org) 在默认情况下如何呈现输出的工件。禁用.LX0输出窗格中的选项,它将显示您期望的输出。

Compiler Explorer 假定输出是程序集,并将其HelloWorld::视为由.LX0选项删除的未使用标签。

在你的第二个例子HelloWorld::中没有被删除,因为它出现在输出的后面,使它看起来好像使用了“标签”,并且由于.LX0过滤器只过滤未使用的标签,它不会删除它。

MSVC 不会发生这种情况,因为 MSVC 的/E输出未显示在程序集窗格中。

通常,如果您想查看完整的未过滤编译器输出,请取消选中程序集窗格中的所有框。(我不知道是否还有其他无法禁用的处理发生。)

另请参阅与选项的表示问题相关的编译器资源管理器问题-E