【发布时间】:2026-01-26 07:55:02
【问题描述】:
我有两个 C 源文件
foo1.c:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
puts("hello world");
return 0;
}
和foo2.c:
#include <stdlib.h>
#include <stdio.h>
void _start(void)
{
puts("hello world");
exit(0);
}
然后我在 i386 GNU/Linux 平台上编译它们:
$ #compile foo1
$ cc -o foo1 foo1.c
$ #compile foo2
$ cc -S foo2.c
$ as -o foo2.o foo2.s
$ ld -o foo2 -dynamic-linker /lib/i386-linux-gnu/ld-linux.so.2 -lc foo2.o
$ #notice that crt1.o and others are missing
从用户的角度来看,输出的可执行文件做同样的事情。
$ ./foo1
hello world
$ ./foo2
hello world
但它们是不同的:
$ wc -c foo1
5000
$ wc -c foo2
2208
$ objdump -d foo1 | wc -l
238
$ objdump -d foo2 | wc -l
35
即使我启用 gcc 的 -Os 选项来优化大小,
$ #compile foo1
$ gcc -o foo1 foo1.c -Os
它并没有小很多:
$ wc -c foo1
4908
$ objdump -d foo1 | wc -l
229
有什么方法可以让 GCC 优化 crt1.o 和我怀疑会导致这个臃肿文件大小的朋友的部分,而不使用非标准代码和奇怪的(在某些情况下可能有害)编译?我的 GCC 的版本字符串是“gcc (Debian 4.9.2-10) 4.9.2”。
【问题讨论】:
-
您是否有想要减小文件大小的动机,或者这纯粹是出于好奇?
-
看看here
-
@EugeneSh。 crt 中的符号已使用,但在我的示例案例中它们没有任何用处。
-
如果他们没有做任何有用的事情 - 他们就不会被使用。
-
如果无法通过链接器将其删除为未使用,则别无选择,只能使用不同的启动代码。