没有标题的C程序

Vik*_*ram 3 c linux compilation dynamic-linking

我在C写"hello world"程序.

void main()
{ printf("Hello World"); }
// note that I haven't included any header file
Run Code Online (Sandbox Code Playgroud)

该程序编译时带有警告

vikram@vikram-Studio-XPS-1645:~$ gcc hello.c 
hello.c: In function ‘main’:
hello.c:2:2: warning: incompatible implicit declaration of built-in function ‘printf’
vikram@vikram-Studio-XPS-1645:~$ ./a.out 
Hello Worldvikram@vikram-Studio-XPS-1645:~$
Run Code Online (Sandbox Code Playgroud)

这怎么可能?操作系统如何在不包含任何标题的情况下链接库?

cni*_*tar 7

printf函数位于C库(libc在您的情况下),它是隐式链接的(实际上gcc有一个内置的printf,但它在点之外).

包含头部不会为链接器带来任何函数,它只是通知编译器它们的声明(即" 它们看起来像什么 ").

显然你应该总是包含头文件,否则你会强迫编译器对函数的外观做出假设.


Jon*_*rdy 6

编译器使用对被调用函数的引用来构建源文件printf(),而不知道它实际需要什么参数或返回类型是什么.生成的组件包含push字符串的地址"Hello World"在程序中的静态数据区,随后callprintf.

将目标文件链接到可执行文件时,链接器会看到printf对C标准库函数的引用并提供它printf().通过巧合,你传递的参数(const char*)是真正的声明兼容printf(),所以它能够正确工作.但请注意,printf()您的程序隐式声明的是返回类型int(我认为),标准printf()也有; 但如果它们不同,并且您要将调用的结果分配给printf()变量,那么您将处于未定义行为的范围内,并且您可能会得到不正确的值.

长话短说:#include正确的标题可以为您使用的函数获取正确的声明,因为这种隐式声明已被弃用,因为它容易出错.