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)
这怎么可能?操作系统如何在不包含任何标题的情况下链接库?
该printf
函数位于C库(libc
在您的情况下),它是隐式链接的(实际上gcc有一个内置的printf,但它在点之外).
包含头部不会为链接器带来任何函数,它只是通知编译器它们的声明(即" 它们看起来像什么 ").
显然你应该总是包含头文件,否则你会强迫编译器对函数的外观做出假设.
编译器使用对被调用函数的引用来构建源文件printf()
,而不知道它实际需要什么参数或返回类型是什么.生成的组件包含push
字符串的地址"Hello World"
在程序中的静态数据区,随后call
到printf
.
将目标文件链接到可执行文件时,链接器会看到printf
对C标准库函数的引用并提供它printf()
.通过巧合,你传递的参数(const char*
)是真正的声明兼容printf()
,所以它能够正确工作.但请注意,printf()
您的程序隐式声明的是返回类型int
(我认为),标准printf()
也有; 但如果它们不同,并且您要将调用的结果分配给printf()
变量,那么您将处于未定义行为的范围内,并且您可能会得到不正确的值.
长话短说:#include
正确的标题可以为您使用的函数获取正确的声明,因为这种隐式声明已被弃用,因为它容易出错.
归档时间: |
|
查看次数: |
1668 次 |
最近记录: |