我读了一本关于试探性定义的书,
暂定定义是没有存储类说明符且没有初始化程序的任何外部数据声明.如果到达翻译单元的末尾并且没有出现具有标识符的初始化器的定义,则暂定定义变为完整定义
请解释上述声明的含义.还有,声明和定义之间的区别?由于这个原因我混淆了.:(为什么这个程序没有错误:
#include <stdio.h>
int a; //Tentative definition
int a; //similarly this declaration too.
int main() //not getting any error with this code why its so?
{
printf("hi");
}
Run Code Online (Sandbox Code Playgroud)
此外,此代码有什么问题:
#include<stdio.h>
printf("Hi");
int main(void){
return 0;
}
Run Code Online (Sandbox Code Playgroud) 考虑由两个文件组成的C程序,
在f1.c:
int x;
Run Code Online (Sandbox Code Playgroud)
f2.c:
int x=2;
Run Code Online (Sandbox Code Playgroud)
我对C99标准第6.9.2段的解读是该程序应该被拒绝.在我对6.9.2的解释中,变量x
是暂定的f1.c
,但是这个暂定的定义在翻译单元的末尾变成了一个实际的定义,并且(在我看来),应该表现得好像f1.c
包含了定义int x=0;
.
对于所有编译器(以及重要的是,链接器)我能够尝试,这不是发生的事情.我试过的所有编译平台都链接了上面两个文件,两个文件中的值x
都是2.
我怀疑这是偶然发生的,或者只是作为标准要求提供的"简单"功能.如果你考虑一下,这意味着链接器中对那些没有初始化器的全局变量有特殊支持,而不是那些显式初始化为零的全局变量.有人告诉我,无论如何编译Fortran可能都需要链接器功能.那将是一个合理的解释.
有什么想法吗?对标准的其他解释?文件f1.c
和f2.c
拒绝链接在一起的平台名称?
注意:这很重要,因为问题出现在静态分析的上下文中.如果这两个文件可能拒绝在某个平台上链接,分析器应该抱怨,但是如果每个编译平台都接受它,那么就没有理由对它进行警告.