0

这只是一个针对基于 C 语言的一般编译器问题。

如果我有一些看起来像这样的代码:

#include "header1.h"
#include "header2.h"
#include "header3.h"
#include "header4.h"  //Header where #define BUILD_MODULE is located

#ifdef BUILD_MODULE

//module code to build

#endif //BUILD_MODULE

即使未定义 BUILD_MODULE,是否会构建与这些标头相关的所有代码?编译器只是“粘贴”标题的内容正确吗?所以这本质上会构建一个只占用空间的无用的一堆或标题代码?

4

3 回答 3

4

标题的所有文本都将包含在编译中,但它们通常几乎没有影响,如下所述。

C 没有任何“头代码”的概念。问题中文件的编译将被视为所有包含文件的内容都出现在单个文件中。那么重要的是内容是否定义了任何对象或功能。

头文件中的大多数声明(因为通常使用头文件)只是声明,而不是定义。他们只是告诉编译器一些事情;它们实际上不会导致创建对象或代码。在大多数情况下,编译器不会从非定义的声明中生成任何数据或代码。

如果头文件定义了外部对象或函数,编译器必须为它们生成数据(或空间)或代码,因为这些对象或函数可以从稍后编译的其他源文件中引用,然后与从当前生成的对象链接汇编。(一些链接器可以确定没有使用外部对象或函数并丢弃它们。)

如果头文件定义了静态对象或函数(准确地说,是具有内部链接或没有链接的对象),那么编译器可以为这些生成数据或代码。但是,优化器应该看到这些对象和函数没有被引用,因此可能会抑制生成。这是一个简单的优化,因为它不需要任何复杂的代码或数据分析,只是观察到没有任何东西依赖于对象或函数。

因此,C 标准不保证不会为静态对象或函数生成数据或代码,但即使是中等质量的 C 实现也应该避免它,除非优化被禁用。

于 2013-07-23T20:58:13.210 回答
1

取决于实际的编译器。优化编译器不会为不需要的代码生成输出,而笨拙的编译器会。

gcc(一个非常常见的用于开源平台的 c 编译器)将使用 -O 选项优化您的代码,该选项不会生成不需要的表达式。

#ifdef 语句中未定义目标的代码永远不会生成输出,因为这会违反语言规范。

于 2013-07-23T20:30:01.970 回答
1

至少从概念上讲,包含/宏处理是独立于编译的一个步骤。读取主源文件并构建一个新的临时文件,其中包含所有包含的代码。如果有任何内容被“#ifdef删除”,则该代码不包含在临时文件中。同时,宏名称的出现被它们“扩展”成的文本替换。将包含所有包含等的结果文件输入到实际的编译器中。

一些编译器从字面上执行此操作(您甚至可以“捕获”中间文件),而其他编译器则模拟它(如果您请求生成中间文件,实际上需要一个完整的单独步骤)。但是大多数编译器都有一种或另一种生成文件供您检查的方法。

C/C++ 标准列出了一些必须遵循的相当晦涩的规则,以确保任何“模拟”实现不会以某种方式改变结果代码的行为,而不是“文字”方法。

于 2013-07-23T20:53:49.337 回答