Как GCC знает, в какой строке находится ошибка, когда компилятор берет все пробелы и комментарии из кода?

Я уверен, что это относится и к другим компиляторам, но я использовал только GCC. Если компилятор оптимизирует код, удаляя все постороннее, что не является кодом (комментарии, пробелы и т. д.), как правильно показать, в какой строке находится ошибка в исходном файле? Оптимизирует ли он код только после проверки на наличие ошибок? Или он каким-то образом вставляет теги, чтобы при обнаружении ошибки он знал, в какой строке он находится?

mycode.cpp: In function ‘foo(int bar)’:
mycode.cpp:59: error: no matching function for call to ‘bla(int bar)’

2 ответов


препроцессор (концептуально) добавляет #line директивы, чтобы сообщить компилятору, какой исходный файл и номер строки соответствуют каждой строке предварительно обработанного источника. Они выглядят как

// set the current line number to 100, in the current source file
#line 100

// set the current line number to 1, in a header file
#line 1 "header.h"

(конечно, современный препроцессор обычно не является отдельной программой и обычно не генерирует промежуточное текстовое представление, поэтому на самом деле это какие-то метаданные, переданные компилятору вместе с потоком предварительно обработанных токенов; но это может быть проще, а не значительно неверно, думать в терминах предварительно обработанного источника).

вы можете добавить их сами, если хотите. Возможные применения-тестирование макросов, использующих __FILE__ и __LINE__ определения, и класть ловушки для программистов обслуживания.


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

в отношении " удаления всего extraneouss, что не является код", это правда в том смысле, что компилятор разбивает входной сигнал и преобразует его в дерево. Но при этом чтение файлов; в каждой точке, это либо чтение файл или доступ к узлу, который был аннотирован, пока файл был читаются.