Всегда ли комментарии обрабатываются до препроцессора?

/*
#define FOO
*/

#ifdef FOO
#define BAR "pirate"
#else
#define BAR "ninja"
#endif

int main() { printf(BAR); getchar(); }

В этом коде FOO не определен (Visual Studio 2008). Я предполагаю, что сначала обрабатываются комментарии, затем препроцессор, а затем код. Всегда ли комментарии обрабатываются до препроцессора? Это часть стандарта?


person Nick Van Brunt    schedule 05.01.2010    source источник


Ответы (6)


Я предполагаю, что сначала обрабатываются комментарии, затем препроцессор, а затем код. Всегда ли комментарии обрабатываются до препроцессора?

Что-то вроде -- часть работы препроцессора заключается в удалении комментариев. В этом случае не важно, что у вас есть директива внутри комментариев; он по-прежнему удален, как и любой другой комментарий.

person John Feminella    schedule 05.01.2010

Согласно стандарту C, при трансляции (компиляции) программы существует 8 фаз трансляции. Каждый комментарий заменяется символом пробела на этапе трансляции 3, тогда как директивы предварительной обработки выполняются на этапе 4.

person Alok Singhal    schedule 05.01.2010

Да, препроцессор заменяет комментарии перед обработкой директив.

Из раздела 5.1.1.2 (Этапы перевода) стандарта C99:

3) Исходный файл разбивается на токены предварительной обработки и последовательности пробельных символов (включая комментарии).... Каждый комментарий заменяется одним пробелом....

4) Выполняются директивы препроцессинга, расширяются вызовы макросов, ....

person jamesdlin    schedule 05.01.2010

Да, с точки зрения стандарта языка комментарии обрабатываются (заменяются пробелами) до препроцессора.

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

В старом и/или нестандартном коде иногда можно увидеть некоторые приемы, основанные на нестандартном поведении, включающем комментарии, специфичные для реализации, и отношения препроцессора, например, создание комментариев с использованием директив препроцессора.

#define CONCAT(a, b) a##b
#define BEGIN_COMMENT CONCAT(/, *)
#define END_COMMENT CONCAT(*, /)

BEGIN_COMMENT
  This code is supposedly commented-out
END_COMMENT

или использование комментариев для конкатенации на уровне препроцессора (с компиляторами C, которые не поддерживают оператор ## в определениях макросов)

#define OLD_CONCAT(a, b) a/**/b

Ни один из таких трюков не является допустимым в стандарте C. Ни один из них не работает.

person AnT    schedule 05.01.2010

Некоторые беглые исследования показывают, что препроцессор преобразует комментарии в пробелы посредством. Итак, все это часть одного и того же потока.

Согласно Википедии, комментарии обрабатываются до директив препроцессора.

person Sapph    schedule 05.01.2010

Да (в каждой разумной вселенной).

person Nifle    schedule 05.01.2010