我有这个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倍。这两个命令行是不是应该产生相同的东西?
答案 0 :(得分:1)
请考虑以下代码。如果定义了FOOBAR
,那么要编译的文件中有 more 代码(在预处理器预处理之后):
#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's (the OP's) answer。我觉得有点详细说明了。
可能导致不同编译对象大小的另一个方面是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
或{{1}时发生的剧烈的大小差异}:
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
答案 1 :(得分:0)
因为gcc根据其扩展决定如何处理输入,所以很傻。真正的等效编译行是:
gcc -I. -c -D SOME_CONTROL_FLAG -x c -o thefile.o thefile.h
其中-x c告诉gcc将.h视为.c
除了一个字节之外,生成的目标文件是相同的,因为包含了文件的名称(我想在调试信息中)。