C 为什么';外部';存储类在函数中的工作方式不同?
下面的代码段工作正常C 为什么';外部';存储类在函数中的工作方式不同?,c,extern,storage-class-specifier,C,Extern,Storage Class Specifier,下面的代码段工作正常 extern int i; int i; int main(){ return 0; } 这里我得到的是,‘I’被声明,然后被定义。因为只有一个定义,所以这很好 int main(){ extern int i; int i; return 0; } 现在,上面的一个给出了以下错误 new.cpp: In function ‘int main()’: new.cpp:5:6: error: redeclaration of ‘int i
extern int i;
int i;
int main(){
return 0;
}
这里我得到的是,‘I’被声明,然后被定义。因为只有一个定义,所以这很好
int main(){
extern int i;
int i;
return 0;
}
现在,上面的一个给出了以下错误
new.cpp: In function ‘int main()’:
new.cpp:5:6: error: redeclaration of ‘int i’
int i;
^
new.cpp:4:13: note: previous declaration ‘int i’
extern int i;
这里有什么问题?这里还有“i”的单一定义。在第二种情况下,在一个范围内有两个
i
声明。一种说法是“在这个函数之外定义了一个变量i
”;另一个表示“此函数中定义了一个变量i
”。如果没有新的作用域,这是不允许的
内部和外部功能的规则是不同的
请注意,您可以使用:
#include <stdio.h>
int i = 21;
int main(void)
{
extern int i;
i = 37;
{
int i = 57;
printf("%d\n", i);
}
printf("%d\n", i);
return 0;
}
#包括
int i=21;
内部主(空)
{
外部国际一级;
i=37;
{
int i=57;
printf(“%d\n”,i);
}
printf(“%d\n”,i);
返回0;
}
这编译正常(除非在使用GCC或Clang时在编译选项中包含-Wshadow
),并在输出上生成57
和37
(如a中所指出)
另请参见要理解差异,您需要熟悉C中一个称为暂定定义的概念。要引用C标准: C11,草案,§6.9.2,外部对象定义 具有文件作用域的对象的标识符声明 没有初始值设定项,也没有存储类说明符或 存储类说明符static构成了一个 定义。如果翻译单元包含一个或多个暂定 标识符的定义,并且翻译单元不包含 该标识符的外部定义,则该行为 就好像翻译单元包含一个文件范围声明一样 标识符,具有转换结束时的复合类型 单位,初始值设定项等于0 您在第一个代码片段中看到的只是对
i
的初步定义。一个对象可以有任意多个暂定定义(但只允许有一个定义):
这是有效的
这里,i
具有外部链接,并已初步定义。如果i
是在同一翻译单元的某个地方定义的,那么这就是i
的实际定义。如果在翻译单元中找不到i
的其他定义,则这将成为完整定义,如同定义如下:
int i = 0;
int main(void) {
return 0;
}
但是第二个片段
inti代码>不是一个暂定定义。只能暂时定义具有外部链接的对象。在第二个代码片段中,声明extern int i代码>表示i
是通过外部链接在其他地方定义的。但是下一行inti代码>表示i
定义时没有链接(本地自动变量没有任何链接——这不是一个暂定定义)。因此,i
的定义存在冲突。因此,第一个片段可以,但第二个片段不行。应该补充说,当我第一次遇到“暂定定义”这个词时,该示例将打印57
然后37
。我在C++中工作,我认为席上不存在这样的东西。是的,C++没有临时定义。
int i = 0;
int main(void) {
return 0;
}