我已经创建了两个头文件和一个这样的cpp文件。
cat.h
class Cat
{
};
dog.h
class Dog
{
};
的main.cpp
#include "cat.h"
#include "dog.h"
int main()
{
Cat my_cat;
return 0;
}
然后我运行g++ -E main.cpp >out.cpp
命令并生成预处理输出。就像这样。
# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cpp"
# 1 "cat.h" 1
class Cat
{
};
# 2 "main.cpp" 2
# 1 "dog.h" 1
class Dog
{
};
# 3 "main.cpp" 2
int main()
{
Cat my_Cat;
return 0;
}
看了这个之后,我想起了几个疑惑。
#
作为注释的语法答案 0 :(得分:1)
让我从我所知道的回答:
#include
指令中。就是这样,没有对真正使用的内容进行分析。这种分析通常在人员或其他工具进行SW重构时完成,而不是由预处理器完成。答案 1 :(得分:1)
关于数字4,这不是注释,这是另一种名为line control directives的指令,并告诉编译器下一段代码来自哪个文件和行。
编译器&#34;正确&#34;只看到translation units(大致是一个包含所有包含的头文件的源文件,就像你创建的那样)所以它实际上并不知道有关头文件的任何信息。行指令是编译器知道头文件中是否存在错误以及头文件中的错误的方法。
答案 2 :(得分:1)
预处理器只对源文件进行文本替换。所以
#include "dog.h"
只是替换为dog.h
。
它不检查源文件的内容以确定是否正在使用dog.h
中的声明。
预处理(临时)文件的位置取决于实现。甚至可能没有这样的文件 - 预处理的文本可能只是直接从预处理器传送到另一个执行编译的可执行文件。
该标准要求实现(编译器和构建链)的行为就像按顺序完成多个阶段一样。一个描述是http://en.cppreference.com/w/cpp/language/translation_phases。但是,实际执行这些阶段不需要特定的实现 - 只需要提供结果,如果有的话。
一般来说,编译器(在某种意义上只是将预处理代码作为输入,并在该链接上实现阶段7)不需要将#
视为注释。但是,由于它是在预处理之后调用的,因此实现可以自由执行。但请注意,预处理器会解释以#
开头的行,因此会拒绝不恰当地执行此操作的代码(例如,您尝试使用#
作为注释标记)。
答案 3 :(得分:0)
预处理器不是编译器。它不理解C,C ++或任何其他语言。它所做的只是处理预处理器指令(#...
)和一些其他任务,如连接字符串文字。当然不能删除死代码。死代码删除由编译器或链接器完成。