我确信这也适用于其他编译器,但我只使用过 GCC。如果编译器通过删除不是代码的所有无关内容(注释、空格等)来优化代码,它如何正确显示原始文件中的哪一行错误?它是否仅在检查错误后才优化代码?或者它是否以某种方式插入标签,以便在发现错误时知道它在哪一行?
mycode.cpp: In function ‘foo(int bar)’:
mycode.cpp:59: error: no matching function for call to ‘bla(int bar)’
我确信这也适用于其他编译器,但我只使用过 GCC。如果编译器通过删除不是代码的所有无关内容(注释、空格等)来优化代码,它如何正确显示原始文件中的哪一行错误?它是否仅在检查错误后才优化代码?或者它是否以某种方式插入标签,以便在发现错误时知道它在哪一行?
mycode.cpp: In function ‘foo(int bar)’:
mycode.cpp:59: error: no matching function for call to ‘bla(int bar)’
编译器将源代码转换为对象格式,或者更准确地说,这里是一种中间格式,稍后将用于生成对象格式。我没有研究过 g++ 的内部结构,但通常情况下,编译器会标记输入并构建树结构。这样做时,它将使用它在文件中读取节点表示的令牌的位置来注释树的节点。在此解析过程中检测到许多错误,但对于那些没有检测到的错误,编译器将使用错误消息中注释节点上的信息。
关于“删除不是代码的所有无关内容”,在编译器标记输入并将其转换为树的意义上,这是正确的。但是这样做时,它正在读取文件;在每一点,它要么读取文件,要么访问在读取文件时被注释的节点。
The preprocessor (conceptually) adds #line
directives, to tell the compiler which source file and line number correspond to each line of preprocessed source. They look like
// 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"
(Of course, a modern preprocessor usually isn't a separate program, and usually doesn't generated an intermediate text representation, so these are actually some kind of metadata passed to the compiler along with the stream of preprocessed tokens; but it may be simpler, and not significantly incorrect, to think in terms of preprocessed source).
You can add these yourself if you want. Possible uses are testing macros that use the __FILE__
and __LINE__
definitions, and laying traps for maintenance programmers.