Что вызывает это несоответствие компилятора при использовании функциональных макросов, содержащих двоеточия? - PullRequest
5 голосов
/ 29 января 2020

Макрос A() будет расширяться только в MSV C, но не в GCC / Clang, если только A() не имеет префикса, например Test A().

. Запустив следующий фрагмент под -E (/E) флаг ( godbolt.org ):

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

A()
B()

Мы видим, MSV C дает следующий вывод:

HelloWorld::
::

А GCC / Clang дает другой вывод:

::

Но затем запустив этот фрагмент:

#define A() HelloWorld::

A()
Test A()

Дает нам следующее на всех 3 компиляторах:

HelloWorld::
Test HelloWorld::

Почему в выходных данных GCC / Clang отсутствует первая строка? Почему он правильно раскрывает все вхождения, когда написано Test A()? Это хорошо определено в стандарте, или это специфично для компилятора c?

1 Ответ

9 голосов
/ 29 января 2020

Это артефакт того, как Compiler Explorer (godbolt.org) представляет вывод по умолчанию. Отключите параметр .LX0 в области вывода, и он представит ожидаемый вывод.

Проводник компилятора предполагает, что вывод является сборкой, и обрабатывает HelloWorld:: как неиспользуемую метку, которая удаляется .LX0 option.

Во втором примере HelloWorld:: не удаляется, потому что он появляется позже в выводе, создавая впечатление, что используется «метка», и поскольку .LX0 фильтрует только неиспользуемые метки, он не удалит его.

С MSV C этого не происходит, поскольку вывод MSV C /E не представлен на панели сборки.

В общем если вы хотите увидеть полный нефильтрованный вывод компилятора, снимите все флажки на панели сборки. (Я не знаю, происходит ли какая-либо другая обработка, которая не может быть отключена.)

См. Также эту проблему обозревателя компиляторов , связанную с проблемами представления с опцией -E.

...