Стандартное поведение пустого макроса перед директивой предварительной обработки - PullRequest
0 голосов
/ 18 ноября 2018

Взять, к примеру, следующее:

#define FOO
FOO #define BAR 1
BAR

Каким, согласно каждому из стандартов ANSI C и C99, должен быть предварительно обработанный вывод вышеуказанного кода?

Мне кажется, это должно быть оценено как 1; однако выполнение приведенного выше примера через gcc -E и clang -E приводит к следующему:

    #define BAR 1
BAR

Ответы [ 3 ]

0 голосов
/ 18 ноября 2018

Проект стандарта «ISO / IEC 9899: проект комитета 201x - 12 апреля 2011 г. N1570», раздел 6.10, фактически содержит пример этого:

ПРИМЕР В:

#define EMPTY 
EMPTY # include <file.h>

последовательность токенов предварительной обработки во второй строке не является директивой предварительной обработки, поскольку она не начинается с символа # в начале фазы 4 трансляции, даже если это произойдет после замены макроса EMPTY.

Он говорит нам, что "... вторая строка не директива предварительной обработки ..."

Так для вашего кода

FOO #define BAR 1

является , а не директивой предварительной обработки, означающей, что будет заменена только FOO, и будет определен BAR , а не . Следовательно, выходной сигнал препроцессора:

 #define BAR 1
BAR
0 голосов
/ 18 ноября 2018

Этот пример фактически встречается в Стандарте (C17 6.10 / 8):

ПРИМЕР В:

#define EMPTY
EMPTY # include <file.h>

последовательность токенов предварительной обработки во второй строке не является директивой предварительной обработки, потому что она не начинается с # в начале фазы 4 трансляции, даже если это произойдет после того, как макрос EMPTY был заменен.

Таким образом, вывод, который вы видите из gcc -E, правильный. (Примечание: количество пробелов здесь не является существенным, на этом этапе перевода программа была переведена в последовательность токенов предварительной обработки ; различные количества пробелов в выходных данных являются всего лишь артефактом того, как gcc -E работает).

0 голосов
/ 18 ноября 2018

Ваш код недействителен

ИСО / МЭК 9899: 2011, раздел 6.10 Директивы предварительной обработки:

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

...