printf 变 puts

/* main.c */
#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("hello world!\n");
	return 0;
}
$ gcc main.c -nostdlib
/usr/bin/ld: 警告: 无法找到项目符号 _start; 缺省为 0000000000001030
/usr/bin/ld: /tmp/cc0k0Sjn.o: in function `main':
main.c:(.text+0x1b): undefined reference to `puts'
collect2: error: ld returned 1 exit status

-nostdlib 选项是让 gcc 不链接标准库。

我本来期望的报错是 undefined reference to 'printf',即未定义 printf 函数。结果 ld 却报了 undefined reference to 'puts',而我写的代码里没有使用 puts 呀。。

原来是:

默认情况下,gcc 会自作聪明地将程序中只使用了一个字符串参数的 pritf 替换成 puts 函数,以提高运行速度。

如果想去除 gcc 的这项优化,我们可以使用 -fno-builtin 选项

$ gcc main.c -nostdlib -fno-builtin
/usr/bin/ld: 警告: 无法找到项目符号 _start; 缺省为 0000000000001030
/usr/bin/ld: /tmp/ccpm0h9E.o: in function `main':
main.c:(.text+0x20): undefined reference to `printf'
collect2: error: ld returned 1 exit status

这样就看到了符合预期的 undefined reference to 'printf'