为了真正符合标准,C中的所有函数(main除外)都必须有原型,即使它们只是在同一个翻译单元中定义之后才使用它们吗?
在以下 C 代码中:
#include <stdio.h>
int main(void){getchar();}
Run Code Online (Sandbox Code Playgroud)
它产生以下汇编:
main:
push rbp
mov rbp, rsp
# no extra instruction here when header is included
call getchar
mov eax, 0
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
但是,如果我不包含stdio.h在文件中,那么它仍然可以编译,但会添加看起来像随机mov eax, 0指令的内容:
这是编译器资源管理器:https : //godbolt.org/z/3fTcss。这只是“未定义行为”的一部分,还是有特殊原因将之前的指令call getchar添加到那里?
最近我学会了C中的隐式函数声明.主要观点很明确,但我对在这种情况下理解链接过程有些麻烦.
请考虑以下代码(文件ac):
#include <stdio.h>
int main() {
double someValue = f();
printf("%f\n", someValue);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试编译它:
gcc -c a.c -std=c99
Run Code Online (Sandbox Code Playgroud)
我看到关于隐式声明功能的警告f().
如果我尝试编译和链接:
gcc a.c -std=c99
Run Code Online (Sandbox Code Playgroud)
我有一个未定义的引用错误.一切都很好.
然后我添加另一个文件(文件bc):
double f(double x) {
return x;
}
Run Code Online (Sandbox Code Playgroud)
并调用下一个命令:
gcc a.c b.c -std=c99
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,一切都成功连接 当然在./a.out调用后我看到了垃圾输出.
所以,我的问题是:如何将隐式声明函数的程序链接起来?在编译器/链接器的引擎下我的例子会发生什么?