Spec-Zone.ru › GCC 5 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 anything else

anything else проверяется на вызовы макросов, которые расширяются. Результат должен соответствовать одному из двух вышеперечисленных вариантов.

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

#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-5.5.0/cpp/Line-Control.html

Spec-Zone.ru

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