Wiki说:
extern
关键字表示"声明而不定义"。换句话说,它是一种显式声明变量或强制声明而无需定义的方法。 也可以明确定义变量,即强制定义。这是通过为变量分配初始化值来完成的。
这意味着,初始化变量的extern
声明用作该变量的定义。所以,
/* Just for testing purpose only */
#include <stdio.h>
extern int y = 0;
int main(){
printf("%d\n", y);
return 0;
}
应该有效(compiled in C++11)。但是当在GCC 4.7.2中使用选项-Wall -Wextra -pedantic -std=c99
进行编译时,会产生警告:
[Warning] 'y' initialized and declared 'extern' [enabled by default]
哪个不应该。 AFAIK,
extern int y = 0;
实际上与
相同int i = 0;
这里出了什么问题?
答案 0 :(得分:6)
此代码完全有效。
但是任何编译器都可以自由发布其他(信息性或非信息性)诊断:
(C99,5.1.1.3p1 fn 8)“当然,只要有效的程序仍然正确翻译,实现就可以自由地产生任意数量的诊断。”
当存在约束或语法违规时,编译器不能执行的操作不会发出诊断信息。
修改强>
当devnull提出OP问题评论时,来自gcc
小组的Joseph Myers在bug report中对此诊断提出质疑:
“这是一种编码风格警告 - 代码有效,但非常有用 因为“extern”一般预期意味着C的单一性 声明没有提供对象的定义。“
答案 1 :(得分:5)
标准的所有三个版本 - ISO / IEC 9899:1990,ISO / IEC 9899:1999和ISO / IEC 9899:2011 - 包含标题为外部对象定义的部分中的示例(C90的第6.7.2节,C99和C11的第6.9.2节)显示:
示例1
int i1 = 1; // definition, external linkage static int i2 = 2; // definition, internal linkage extern int i3 = 3; // definition, external linkage int i4; // tentative definition, external linkage static int i5; // tentative definition, internal linkage
示例继续,但extern int i3 = 3;
行清楚地表明标准表明应该允许它。但请注意,标准中的示例在技术上并非“规范”(参见标准中的前言);它们不是关于什么是允许的和不允许的最终陈述。
尽管如此,大多数人大部分时间都不使用extern
和初始化程序。