Spec-Zone.ru › GCC 4 CPP

6 Управление строками

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

Если вы пишете программу, которая генерирует исходный код, например, генератор синтаксического анализа bison, вы можете вручную скорректировать представление препроцессора текущего имени файла и номера строки. Части выходных данных bison генерируются с нуля, другие части взяты из стандартного файла синтаксического анализа. Остальные скопированы дословно из входных данных bison. Вам нужно, чтобы сообщения об ошибках компилятора и символьные отладчики могли ссылаться на входной файл bison.

Программа bison или любая подобная программа может организовать это, записав директивы ‘#line’ в выходной файл. Директива ‘#line’ задаёт исходный номер строки и имя исходного файла для последующего ввода в текущем входном файле препроцессора. Директива ‘#line’ имеет три варианта:

#line linenum
linenum — это неотрицательное десятичное целое число. Оно задаёт номер строки, который должен быть показан для следующей строки ввода. Последующие строки считаются с linenum.
#line linenum filename
linenum — такое же, как в первом варианте, и имеет такой же эффект. Кроме того, filename — это строковая константа. Следующая строка и все последующие строки отображаются как взятые из указанного файла, пока это не изменится. filename интерпретируется по обычным правилам для строковой константы: обратные слеши интерпретируются. Это отличается от ‘#include’.

Предыдущие версии CPP не интерпретировали экранированные последовательности в ‘#line’; мы изменили это, потому что стандарт требует их интерпретации, и большинство других компиляторов это делают.

#line любое другое значение
любое другое значение проверяется на вызовы макросов, которые расширяются. Результат должен соответствовать одному из двух вышеупомянутых форматов.

Директивы ‘#line’ изменяют результаты предопределённых макросов __FILE__ и __LINE__ с этого момента. См. Стандартные предопределённые макросы. Они не влияют на представление #include каталога, содержащего текущий файл. Это изменение по сравнению с GCC 2.95. Раньше чтение файла

#line 1 "../src/gram.y"
#include "gram.h"

искало gram.h в ../src, а затем по цепочке -I; каталог, содержащий физический исходный файл, не проверялся. В GCC 3.0 и более поздних версиях ‘#include’ не зависит от наличия ‘#line’, указывающей на другой каталог.

Мы внесли это изменение, потому что старое поведение вызывало проблемы при переносе сгенерированных исходных файлов между машинами. Например, распространение сгенерированных парсеров с исходным релизом является распространённой практикой, чтобы пользователи не нуждались в установке yacc или Bison. Эти файлы часто содержат директивы ‘#line’, ссылающиеся на древо каталогов системы, где был создан релиз. Если GCC попытается найти заголовочные файлы в этих каталогах, сборка, скорее всего, завершится неудачей.

Новое поведение также может привести к ошибкам, если сгенерированный файл не находится в той же директории, что и его исходный код, и он пытается включить заголовок, который был бы виден при поиске из каталога, содержащего исходный файл. Однако эту проблему легко решить с помощью дополнительного параметра -I в командной строке. Ошибки, вызванные старой семантикой, иногда можно было исправить только редактированием сгенерированных файлов, что сложно и чревато ошибками.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/cpp/Line-Control.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API