6

下面给定的程序正在工作,但不包括<stdio.h>?为什么这行得通?

int main()
{
    printf("integra");
    return 0;
}
4

6 回答 6

8

printf() 的定义在 libc.so 中,即使您不包含头文件,动态链接器也会处理它。在编译期间,printf() 将是一个未定义的符号,它假定它稍后可能会在 libc 中找到该定义。头文件将只给出原型类型并禁止编译器(警告)说明原型的定义存在于 glibc 中。所以基本上,包含头文件只是为了确保定义在我们的库中可用,以帮助开发人员。

于 2011-01-12T05:56:33.680 回答
7

在旧标准中,未声明的函数假定int参数和返回值。您char*的大小(32 位)与 相同int,因此一切正常。

只是不要这样做。

于 2011-01-11T04:27:02.937 回答
5

printf() 仅在 libc.so 中定义

动态链接器将解析 libc 中的符号 printf(),因为您没有包含它

libc 在 gcc 中是每个程序的默认值

于 2011-01-11T05:48:34.063 回答
4

正如 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
$
于 2011-01-12T01:53:52.887 回答
1

一些(旧的?)编译器在调用函数之前不需要原型。

于 2011-01-11T04:24:33.903 回答
1

当您使用尚未声明的函数时,编译器将假定此函数返回 anint并采用未指定但固定数量的参数。

如果这个假设与函数的定义匹配,并且如果您提供的参数也匹配(以默认参数提升为模)函数期望接收的参数,那么一切都很好。
如果假设不正确(例如 for printf,它是一个可变参数函数),或者当参数不匹配时,结果是未定义的。未定义行为的令人讨厌的事情之一是它看起来可以按预期工作。

于 2011-01-11T13:34:54.303 回答