繁体   English   中英

为什么用D选项编译头文件会导致文件比使用C包装器头大得多?

[英]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).

基于此,以及我在第一部分中使用的代码,我们可以观察到在将您的代码编译为cc-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM