如何定义外部变量以及声明?

时间:2014-06-26 17:29:02

标签: c c99 extern gcc-warning initializer

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;  

这里出了什么问题?

2 个答案:

答案 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和初始化程序。