为什么下面的C代码中的变量的多重定义没有错误?

时间:2015-09-08 05:54:27

标签: c gcc extern

我有两个2个文件:

交流转换器:

#include <stdio.h>

extern int i = 5;

int main(){
    prnt();
}

b.c:

#include <stdio.h>

int i;

void prnt(){
    printf("%d",i);
}

使用gcc a.c b.c链接在一起时编译程序。获得的输出是5。 gcc编译器不应该提出错误multiple definiton of i,因为在ac中,变量i都是声明已定义,而在bc中,语句{{1已知用隐藏的extern隐式定义 0 的值?

3 个答案:

答案 0 :(得分:5)

首先,为了避免混淆,extern int i = 5;int i = 5;完全相同。这是一个定义,因为C11 6.9.2 / 1:

  

如果对象标识符的声明具有文件范围和初始化程序,则声明是标识符的外部定义

(请注意,“外部定义”在此处表示文件范围内的定义 - 不要与“外部链接”混淆。)

int i;被称为暂定定义;在这种情况下,它的行为与int i = 0;相同(由6.9.2 / 2定义),确认它是一个定义。由于6.2.2 / 5:

,它有外部联系
  

如果对象的标识符声明具有文件范围而没有存储类说明符,则其链接是外部的。

因此,这两个定义都定义了i与外部链接。 C标准第6.2.2 / 2节说:

  

[...]具有外部链接的特定标识符的每个声明表示相同的对象或功能。

因此,这两个i都表示同一个对象。

从6.9 / 5:

  

如果在表达式中使用通过外部链接声明的标识符(除了作为sizeof或_Alignof运算符的操作数的一部分,其结果是整数常量),整个程序中的某处应该正好一个标识符的外部定义

由于您为i提供了两个定义,因此您的程序违反了此规则,导致未定义的行为,无需诊断。

规则违规的参考是未定义的行为是4/2:

  

如果违反约束或运行时约束之外的''shall''或''shall not''要求,则行为未定义。

6.9 / 5中的引用部分是“语义:”,而不是“约束:”,因此它被视为出现在约束之外。

答案 1 :(得分:-1)

这个问题的答案是:

  • 声明可以进行多次,但只能定义一次。
  • 如果仅声明变量并且还为该声明提供初始化器,则将分配该变量的存储器,即该变量将被视为已定义。 所以extern int i = 5;它声明以及为变量分配内存 现在我们可以多次声明i变量。

答案 2 :(得分:-2)

答案是“声明可以进行多次,而定义只能进行一次”

为了清楚说明,只要在变量之前使用“extern”关键字,就意味着只是声明了变量。

extern int i = 5; - &GT;这只是声明一个变量

int i; ---&GT;定义并宣布