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

hac*_*cks 14 c c99 initializer extern gcc-warning

维基说:

extern关键字的意思是"没有限定声明".换句话说,它是一种显式声明变量或强制声明而无需定义的方法.也可以明确定义变量,即强制定义.这是通过为变量分配初始化值来完成的.

这意味着,初始化变量extern声明用作该变量的定义.所以,

/* Just for testing purpose only */ 
#include <stdio.h>
extern int y = 0;
int main(){
    printf("%d\n", y);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

应该是有效的(在C++ 11中编译).但是当使用-Wall -Wextra -pedantic -std=c99GCC 4.7.2中的选项进行编译时,会产生警告:

[Warning] 'y' initialized and declared 'extern' [enabled by default]
Run Code Online (Sandbox Code Playgroud)

哪个不应该.据我所知,

extern int y = 0;  
Run Code Online (Sandbox Code Playgroud)

实际上是一样的

int i = 0;  
Run Code Online (Sandbox Code Playgroud)

这里出了什么问题?

Jon*_*ler 8

该标准的所有三个版本 - 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
Run Code Online (Sandbox Code Playgroud)

示例仍在继续,但该extern int i3 = 3;行清楚地表明标准表明应该允许它.但请注意,标准中的示例在技术上并非"规范"(参见标准中的前言); 它们不是关于什么是允许的和不允许的明确声明.

也就是说,大多数人大部分时间都不使用extern初始化程序.


oua*_*uah 7

此代码完全有效.

但是任何编译器都可以自由发布其他(信息性或非信息性)诊断:

(C99,5.1.1.3p1 fn 8)"当然,只要有效的程序仍然正确翻译,实现就可以自由地产生任意数量的诊断."

当存在约束或语法违规时,编译器不能执行的操作不会发出诊断信息.

编辑:

正如devnull提出的OP问题评论,来自gcc团队的Joseph Myers 在一个错误报告中解释了质疑这个诊断:

"这是一种编码风格警告 - 代码是有效的,但对于C来说非常单一,因为"extern"通常被认为意味着声明没有提供对象的定义."