下面给定的程序正在工作,但不包括<stdio.h>
?为什么这行得通?
int main()
{
printf("integra");
return 0;
}
下面给定的程序正在工作,但不包括<stdio.h>
?为什么这行得通?
int main()
{
printf("integra");
return 0;
}
printf() 的定义在 libc.so 中,即使您不包含头文件,动态链接器也会处理它。在编译期间,printf() 将是一个未定义的符号,它假定它稍后可能会在 libc 中找到该定义。头文件将只给出原型类型并禁止编译器(警告)说明原型的定义存在于 glibc 中。所以基本上,包含头文件只是为了确保定义在我们的库中可用,以帮助开发人员。
在旧标准中,未声明的函数假定int
参数和返回值。您char*
的大小(32 位)与 相同int
,因此一切正常。
只是不要这样做。
printf() 仅在 libc.so 中定义
动态链接器将解析 libc 中的符号 printf(),因为您没有包含它
libc 在 gcc 中是每个程序的默认值
正如 Abi 指出的那样,您的代码在不包含 stdio.h 的情况下成功构建,因为链接器默认为未定义符号 ( printf
) 的系统 std 库。GCC 通常会警告您此类情况。
让 test.c 为:
1: int main()
2: {
3: printf("test\n");
4: return 0;
5: }
在 Mac OSX 上使用 GCC 4.2.1 构建 test.c:
$ gcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
$ ./a.out
test
您可以通过指定 GCC 链接器选项-nostdlib
(或-nodefaultlibs
)以及-lgcc
(如 GCC 手册建议的那样)来禁用此默认链接:
$ gcc -nostdlib -lgcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
Undefined symbols:
"_puts", referenced from:
_main in cc3bvzuM.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
一些(旧的?)编译器在调用函数之前不需要原型。
当您使用尚未声明的函数时,编译器将假定此函数返回 anint
并采用未指定但固定数量的参数。
如果这个假设与函数的定义匹配,并且如果您提供的参数也匹配(以默认参数提升为模)函数期望接收的参数,那么一切都很好。
如果假设不正确(例如 for printf
,它是一个可变参数函数),或者当参数不匹配时,结果是未定义的。未定义行为的令人讨厌的事情之一是它看起来可以按预期工作。