0

I have this C file that serves as a wrapper for a header file:

#define SOME_CONTROL_FLAG
#include "thefile.h"

If I compile with this:

gcc -I. -c -o thefile.o thefile.c

I get a 9 kB object file. However, if I do this instead:

gcc -I. -c -D SOME_CONTROL_FLAG -o thefile.o thefile.h

I get a 3 MB object file! That's ~300 times larger. Aren't those two command lines supposed to yield the same thing?

4

2 回答 2

1

一般来说,用不同的符号编译会编译不同的代码

考虑以下代码。如果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's)的回答。我觉得有必要对它进行更多的阐述。

另一个可能导致不同编译对象大小的方面是 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).

基于此,以及我在第一部分中使用的代码,我们可以观察到当我们将代码编译为或 as时发生的巨大大小差异: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
于 2013-10-29T17:21:24.947 回答
0

Because gcc decides what to do with the input based on its extension, silly me. The true equivalent compilation line is:

gcc -I. -c -D SOME_CONTROL_FLAG -x c -o thefile.o thefile.h

Where -x c tells gcc to treat the .h as a .c

The resulting object files are identical save for one byte, because the file's name is included (in the debug info, I suppose).

于 2013-10-29T17:37:52.170 回答