C中的extern关键字是冗余的吗?

Har*_*sha 1 c keyword extern

我发现我可以在不使用extern的情况下达到预期的效果(尽管我同意它会给读者一些关于变量的暗示).在某些情况下,使用extern会产生不希望的结果.

xyz.h

int i;
Run Code Online (Sandbox Code Playgroud)

在file1.c

#include "xyz.h"
....
i=10;
....
Run Code Online (Sandbox Code Playgroud)

file2.c中

#include "xyz.h"
main()
{
printf("i=%d\n",i);
}
Run Code Online (Sandbox Code Playgroud)

当然,这是一个大项目,为了简单的理解而将其分解.使用extern关键字,我无法获得理想的结果.实际上,我通过"extern"方法得到变量i的链接器错误.

代码采用"extern"方法,

在file1.c

int i;
main()
{
i=10;
}
Run Code Online (Sandbox Code Playgroud)

file2.c中

extern int i;
foo()
{
printf("i=%d\n",i);
}
Run Code Online (Sandbox Code Playgroud)

这给链接器错误.我只是想知道它为什么在第一种情况下工作,以及在没有使用关键字"extern"的情况下我们无法做到的实际情况.谢谢.

AnT*_*AnT 6

正式地,您的第一个程序无效.在头文件中定义变量然后将该头文件包括到多个翻译单元中将最终导致具有外部链接的同一实体的多个定义.这是C中的约束违规.

6.9外部定义

5外部定义是外部声明,它也是函数(内联定义除外)或对象的定义.如果在表达式中使用通过外部链接声明的标识符(而不是作为sizeof运算符的操作数的一部分,其结果是整数常量),则整个程序中的某个地方应该只有一个标识符的外部定义; 否则,不得超过一个.

的定义i中的第一个例子是一个暂定的定义(因为它已在评论被提到),但它变成一个常规的完全成熟的外部定义i在每个翻译单元,其包括头文件的末尾.因此,该定义的"暂定性"并未改变"整个计划"的观点.这与手头的事情并没有密切关系(除了下面的一点评论).

是什么让你的第一个例子编译没有错误是一个流行的编译器扩展,甚至在语言标准中也提到了这一点.

J.5常用扩展

J.5.11多个外部定义

1对象的标识符可能有多个外部定义,无论是否明确使用关键字extern; 如果定义不一致,或者初始化了多个,则行为未定义(6.9.2).

(最初导致C中编译器扩展的原因很可能是暂定定义支持的一些实现特性,但在抽象语言层面,暂定定义与此无关.)

您的第二个程序有效i(BTW,intC中不再支持隐式).我不知道你怎么能从它得到任何链接器错误.