[英]Why does compiling a header file with a D option result in a much bigger file than using a C wrapper for the header?
我有这个C文件,用作头文件的包装:
#define SOME_CONTROL_FLAG
#include "thefile.h"
如果我用这个编译:
gcc -I. -c -o thefile.o thefile.c
我得到一个9 kB的目标文件。 但是,如果我改为这样做:
gcc -I. -c -D SOME_CONTROL_FLAG -o thefile.o thefile.h
我得到一个3 MB的目标文件! 大约大300倍。 这两个命令行不是应该产生相同的结果吗?
考虑下面的代码。 如果定义了FOOBAR
,则文件中还有更多代码需要编译(在预处理程序对其进行预处理之后):
#ifdef FOOBAR
int foo(int bar) {
return bar + bar;
}
#endif
int bar(int baz) {
return 1+baz;
}
使用FOOBAR定义的编译会更改输出的大小。 没有FOOBAR的是1232,而没有FOOBAR的是1328。这不是一个很大的差异,但这是一个差异。
$ gcc -c code.c -o code.o
$ ls -l code.o
-rw-rw-r-- 1 user user 1232 Oct 29 13:19 code.o
$ gcc -DFOOBAR -c code.c -o code.o
$ ls -l code.o
-rw-rw-r-- 1 user 1328 Oct 29 13:19 code.o
如果有很多条件代码,这可能非常重要。 例如,定义符号可能会导致包含很多平台特定的代码,而未定义符号可能会使函数实现成为存根。
注意:此部分基于Urhixidur(OP)的答案 。 我觉得有必要对其进行详细说明。
导致不同的编译对象大小的另一个方面是GCC实际正在编译的内容。 在你的例子中
gcc -I. -c -D SOME_CONTROL_FLAG -o thefile.o thefile.h
头文件正在编译中,GCC根据文件扩展名检测到它正在使用c-header
语言进行编译。 但是,实际上您正在编译头文件并生成一个.o
文件,这表明您要将其编译为C,在这种情况下,应使用GCC的-x
选项。 关于它,手册页说:
-x language
Specify explicitly the language for the following input files (rather than letting the compiler choose a default based on the file name suffix). This option applies to all
following input files until the next -x option. Possible values for language are:
c c-header cpp-output
c++ c++-header c++-cpp-output
objective-c objective-c-header objective-c-cpp-output
objective-c++ objective-c++-header objective-c++-cpp-output
assembler assembler-with-cpp
ada
f77 f77-cpp-input f95 f95-cpp-input
go
java
-x none
Turn off any specification of a language, so that subsequent files are handled according to their file name suffixes (as they are if -x has not been used at all).
基于此,以及我在第一部分中使用的代码,我们可以观察到在将您的代码编译为c
或c-header
时发生的巨大的大小差异:
$ gcc -c code.h -o code.o # as a header
$ ls -l code.o
-rw-rw-r-- 1 user user 1470864 Oct 29 14:04 code.o
$ gcc -c -x c code.h -o code.o # as c code
$ ls -l code.o
-rw-rw-r-- 1 user user 1232 Oct 29 14:04 code.o
请注意,尽管编译(作为标题)似乎不受符号定义的影响:
$ gcc -c code.h -o code.o
$ ls -l code.o
-rw-rw-r-- 1 user user 1470864 Oct 29 14:06 code.o
$ gcc -DFOOBAR -c code.h -o code.o
$ ls -l code.o
-rw-rw-r-- 1 user user 1470864 Oct 29 14:06 code.o
因为gcc根据其扩展名决定如何处理输入,所以我很傻。 真正等效的编译行是:
gcc -I. -c -D SOME_CONTROL_FLAG -x c -o thefile.o thefile.h
-xc告诉gcc将.h视为.c
生成的目标文件是相同的,只是保留了一个字节,因为其中包含了文件名(我想是在调试信息中)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.