Spec-Zone.ru › GCC 6 CPP

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

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

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

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

#line linenum

linenum — это целая десятичная константа, неотрицательное целое число. Она указывает номер строки, который должен быть указан для следующей строки ввода. Последующие строки считаются с linenum.

#line linenum filename

linenum такой же, как и в первом варианте, и имеет тот же эффект. Кроме того, filename — это строковая константа. Следующая строка и все последующие строки указываются как полученные из указанного файла, пока что-то не изменит это. filename интерпретируется согласно обычным правилам для строковой константы: обратные слэши интерпретируются. Это отличается от «#include».

Предыдущие версии CPP не интерпретировали escapes в «#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-6.5.0/cpp/Line-Control.html

Spec-Zone.ru

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