关于暂定定义

Sad*_*que 34 c

我读了一本关于试探性定义的书,

暂定定义是没有存储类说明符且没有初始化程序的任何外部数据声明.如果到达翻译单元的末尾并且没有出现具有标识符的初始化器的定义,则暂定定义变为完整定义

请解释上述声明的含义.还有,声明和定义之间的区别?由于这个原因我混淆了.:(为什么这个程序没有错误:

#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)

Tyl*_*nry 63

变量声明说:"程序中有一个具有以下名称和类型的变量".

变量定义说:"亲爱的Compiler先生,请为具有以下名称和类型的变量分配内存."

因此,同一个变量可以有多个声明,但应该只有一个定义.

在C中,纯声明(也不是定义)前面是关键字extern.因此,由于您的第一个示例中没有此关键字,因此您拥有两个定义.从表面上看,这似乎是一个问题(实际上是C++中的一个错误),但C有一个特殊的"暂定"定义规则,它允许同一个变量的多个定义,只要它们都匹配,最多只有一个有一个初始化程序.幕后的C编译器将所有暂定定义组合到一个定义中.

您是否尝试初始化两个定义,如下所示:

int a = 1;
int a = 2;
Run Code Online (Sandbox Code Playgroud)

然后你会有一个错误.

你的第二个问题更直截了当.在C中,您根本无法在函数体外部使用可执行语句.这是不允许的.想一想:如果允许的话,你什么时候会期望它运行?

  • @ legends2k不,这在C中并不违法...在您链接的问题(以及链接到链接的答案的问题)涉及多个文件.同一文件中的多个(兼容)暂定定义不是违规.该问题的违反是因为,在翻译单元结束时,如果存在没有完整定义的暂定定义,则暗示了完整的定义.加上多个文件会在链接时导致多个定义(除了暂定定义规则的公共扩展以跨越多个文件). (6认同)

Jer*_*fin 11

第一个是有效的,因为你的定义a都是暂定的,可以根据你的需要随时复制.在翻译单元的末尾,没有看到非暂定的定义,因此您为属性指定的内容与默认值组合以给出最终定义a,因此它将具有外部链接,静态存储持续时间,并且初始化为0.

第二个问题与暂定定义无关.你printf("Hi");需要在一个功能内部工作 - 它不是一个声明或定义(暂定或其他); 它只是不被允许.