“自作聪明”的 GCC
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'
。