Что касается синтаксического анализа директив препроцессора, стандарт C99 (и стандарт C89 до него) четко определял последовательность операций, логически выполняемых компилятором. В частности, я считаю, что это означает, что этот код:
/* */ # /* */ include /* */ <stdio.h> /* */
эквивалентно:
#include <stdio.h>
Хорошо это или плохо, но GCC 3.4.4 с '-std = c89 -pedantic', в любом случае, принимает строку с комментариями. Я не защищаю это как стиль - ни на секунду (это ужасно). Я просто думаю, что это возможно.
В разделе 5.1.1.2 «Фазы перевода» ИСО / МЭК 9899: 1999 говорится:
[Сопоставление символов, включая триграфы]
[Соединение строк - удаление новой строки с обратной косой чертой]
Исходный файл разбивается на токены предварительной обработки и последовательности символов пробела (включая комментарии). Исходный файл не должен заканчиваться токеном частичной предварительной обработки или частичным комментарием. Каждый комментарий заменяется одним пробелом. Символы новой строки сохраняются. Будет ли каждая непустая последовательность символов пробела, кроме новой строки, сохраняться или заменяться одним символом пробела, определяется реализацией.
Выполняются директивы предварительной обработки, расширяются вызовы макросов, [...]
Раздел 6.10 Директивы предварительной обработки говорит:
Директива предварительной обработки состоит из последовательности токенов предварительной обработки, которая начинается с токена предварительной обработки #, который (в начале фазы трансляции 4) является либо первым символом в исходном файле (необязательно после пробела, не содержащего символов новой строки), либо которым следует за пробелом, содержащим хотя бы один символ новой строки, и заканчивается следующим символом новой строки.
Единственный возможный спор - это выражение в скобках «(в начале фазы 4 перевода)», которое может означать, что комментарии перед хешем должны отсутствовать, поскольку в противном случае они не заменяются пробелами до конца фазы 4.
Как отмечали другие, предварительные стандартные препроцессоры C не вели себя единообразно во многих отношениях, а пробелы перед и в директивах препроцессора были одной из областей, где разные компиляторы делали разные вещи, в том числе не распознавали директивы препроцессора с пробелами перед ними. .
Примечательно, что удаление обратной косой черты и новой строки происходит до анализа комментариев. Следовательно, не следует заканчивать //
комментарии обратной косой чертой.