是什么导致编译器在使用包含冒号的类函数宏时出现差异?
What causes this compiler discrepancy whilst using function-like macros containing colons?
A()
宏只会在 MSVC 上展开,而不会在 GCC/Clang 上展开,除非 A()
放置有前缀,例如Test A()
.
通过 运行 -E
(/E
) 标志 (godbolt.org) 下的以下代码段:
#define A() HelloWorld::
#define B() ::
A()
B()
我们看到 MSVC 给出了以下输出:
HelloWorld::
::
而GCC/Clang给出了不同的输出:
::
但是 运行 这个片段:
#define A() HelloWorld::
A()
Test A()
为我们提供所有 3 个编译器的以下信息:
HelloWorld::
Test HelloWorld::
为什么 GCC/Clang 输出缺少第一行?
为什么在写入 Test A()
时它会正确展开所有出现的地方?
这是在标准中明确定义的,还是特定于编译器的?
这是 Compiler Explorer (godbolt.org) 默认情况下如何呈现输出的产物。禁用输出窗格中的 .LX0
选项,它将显示您期望的输出。
Compiler Explorer 假定输出是程序集,并将 HelloWorld::
视为未使用的标签,由 .LX0
选项删除。
在你的第二个例子中 HelloWorld::
没有被删除,因为它稍后出现在输出中使得它看起来好像使用了 "label" 并且因为 .LX0
只过滤标签未使用,它不会删除它。
MSVC 不会发生这种情况,因为 MSVC 的 /E
输出未显示在程序集窗格中。
一般来说,如果您想查看完整的未经过滤的编译器输出,请取消选中汇编窗格中的所有框。 (我不知道是否还有其他无法禁用的处理正在发生。)
另请参阅 this Compiler Explorer issue 与 -E
选项的显示问题有关。
A()
宏只会在 MSVC 上展开,而不会在 GCC/Clang 上展开,除非 A()
放置有前缀,例如Test A()
.
通过 运行 -E
(/E
) 标志 (godbolt.org) 下的以下代码段:
#define A() HelloWorld::
#define B() ::
A()
B()
我们看到 MSVC 给出了以下输出:
HelloWorld::
::
而GCC/Clang给出了不同的输出:
::
但是 运行 这个片段:
#define A() HelloWorld::
A()
Test A()
为我们提供所有 3 个编译器的以下信息:
HelloWorld::
Test HelloWorld::
为什么 GCC/Clang 输出缺少第一行?
为什么在写入 Test A()
时它会正确展开所有出现的地方?
这是在标准中明确定义的,还是特定于编译器的?
这是 Compiler Explorer (godbolt.org) 默认情况下如何呈现输出的产物。禁用输出窗格中的 .LX0
选项,它将显示您期望的输出。
Compiler Explorer 假定输出是程序集,并将 HelloWorld::
视为未使用的标签,由 .LX0
选项删除。
在你的第二个例子中 HelloWorld::
没有被删除,因为它稍后出现在输出中使得它看起来好像使用了 "label" 并且因为 .LX0
只过滤标签未使用,它不会删除它。
MSVC 不会发生这种情况,因为 MSVC 的 /E
输出未显示在程序集窗格中。
一般来说,如果您想查看完整的未经过滤的编译器输出,请取消选中汇编窗格中的所有框。 (我不知道是否还有其他无法禁用的处理正在发生。)
另请参阅 this Compiler Explorer issue 与 -E
选项的显示问题有关。