Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes this compiler discrepancy whilst using function-like macros containing colons?

The A() macro will only expand on MSVC, but not GCC/Clang unless A() is placed with a prefix e.g. Test A().

By running the following snippet under the -E (/E) flag (godbolt.org):

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

A()
B()

We see MSVC gives the following output:

HelloWorld::
::

And GCC/Clang gives a different output:

::

But then running this snippet:

#define A() HelloWorld::

A()
Test A()

Gives us the following on all 3 compilers:

HelloWorld::
Test HelloWorld::

Why is the GCC/Clang output missing the first line? Why does it expand all occurrences correctly when Test A() is written? Is this well defined within the standard, or is this compiler-specific?

like image 326
Yorek B Avatar asked Jan 29 '20 17:01

Yorek B


1 Answers

This is an artifact of how Compiler Explorer (godbolt.org) presents the output by default. Disable the .LX0 option in the output pane and it will present the output that you expect.

Compiler Explorer assumes that the output is assembly and treats HelloWorld:: as an unused label that is removed by the .LX0 option.

In your second example HelloWorld:: is not removed, because it appears later in the output making it seem as if the "label" is used and since .LX0 filters only labels that are unused, it will not remove it.

It doesn't happen with MSVC, because MSVC's /E output is not presented in the assembly pane.

In general if you want to see the full unfiltered compiler output uncheck all the boxes in the assembly pane. (I don't know whether there is any other processing happening that can't be disabled.)

See also this Compiler Explorer issue relating to presentation problems with the -E option.

like image 114
walnut Avatar answered Nov 07 '22 02:11

walnut