Учитывая этот кусок C код:#line и строковый литерал конкатенации
char s[] =
"start"
#ifdef BLAH
"mid"
#endif
"end";
что следует вывод препроцессора быть? Другими словами, что должен получать и иметь возможность обрабатывать фактический компилятор? Чтобы сузить возможности, давайте придерживаться C99.
Я вижу, что некоторые препроцессоры выход это:
#line 1 "tst00.c"
char s[] =
"start"
#line 9
"end";
или это:
# 1 "tst00.c"
char s[] =
"start"
# 7 "tst00.c"
"end";
НКУ -E выводит это:
# 1 "tst00.c"
# 1 "<command-line>"
# 1 "tst00.c"
char s[] =
"start"
"end";
И НКУ прекрасно подходит компилирование весь вышеуказанный предварительно обработанный код даже с -fpreprocessed это означает, что дальнейшая предварительная обработка не должна выполняться, поскольку все это уже сделано.
Путаница проистекает из этой формулировки стандарта 1999 C:
5.1.1.2 Translation phases
1 The precedence among the syntax rules of translation is specified by the following
phases.
...
4. Preprocessing directives are executed, macro invocations are expanded, and
_Pragma unary operator expressions are executed. ... All preprocessing directives are
then deleted.
...
6. Adjacent string literal tokens are concatenated.
7. White-space characters separating tokens are no longer significant. Each
preprocessing token is converted into a token. The resulting tokens are syntactically
and semantically analyzed and translated as a translation unit.
Другими словами, это законно для #line
директивы появляться между соседними строковых литералов? Если это так, это означает, что фактический компилятор должен выполнить еще один раунд конкатенации строковых литералов, но это не упоминается в стандарте.
Или мы просто имеем дело с нестандартными реализациями компилятора, включенными gcc?
Я не уверен насчет \ _ \ _ LINE \ _ \ _ и \ _ \ _ FILE \ _ \ _. Они должны были быть расширены во время предварительной обработки.Кроме того, #line не только для читателей с запрограммированным кодом. Достойному компилятору нужны эти директивы #line для создания значимых ошибок, указывающих местоположение проблемы в исходном коде. –
@AlexeyFrunze Я сказал: «вы можете вставить в уже предварительно обработанный файл». Нет, компилятор не должен позволять '# строке' определять, как сообщения об ошибках сообщаются в сообщениях. – Potatoswatter
Да, я думаю, ключ состоит в том, что токеты предварительной обработки становятся токенами, а интерфейсы на этой границе не стандартизированы. –