为什么我没有在全局范围内收到重新声明错误
这段代码没有给我重新声明错误。
#include<stdio.h>
int i;
int i = 27;
int main()
{
printf("%d",i);
return 0;
}
据我说,我声明并定义了一个未初始化的全局变量,默认值为 0。后来重新声明,重新定义并为其分配了27个值。我期待它给出重新声明错误,因为两个i都在相同的范围内(全局)。
但我没有收到任何错误,为什么?
但是下面的代码给了我一个预期的重新声明错误,因为它们在相同的范围内定义。
#include<stdio.h>
int main()
{
int i;
int i = 27;
printf("%d",i);
return 0;
}
回答
在文件范围内,这个:
int i;
由于没有初始值设定项,因此是一个暂定定义。如果没有其他定义出现,它将被视为外部定义。
当你这样做时:
int i = 27;
这构成一个外部定义为i其中现有暂定定义相匹配。
这些术语在C 标准的第 6.9.2 节 p1 和 p2 中定义:
1如果对象的标识符声明具有文件作用域和初始值设定项,则该声明是标识符的外部定义。
2具有文件作用域的对象的标识符声明,没有初始值设定项,没有存储类说明符或带有存储类说明符
static,构成了一个
暂定定义。如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,则行为就像翻译单元包含该标识符的文件范围声明一样,复合类型为翻译单元的末尾,初始化等于 0。
您的第二个代码片段在块范围(而不是文件范围)中定义了一个变量,然后在同一范围内再次定义它。这构成了变量重新定义。
- @PranjalChandra: The issue is not really whether multiple declarations are allowed but that `int foo;` is not a full definition in file scope but is a full definition in block scope. This is largely historic; programs were written using `int foo;` as declarations in file scope before C was fully settled, so they had to be tolerated as non-definition declarations. But they also had to create an object if no full definition was given, and thus the category of tentative definitions was created. If we were redesigning the language today, this would probably be changed.