我有两个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 的值?
答案 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)
这个问题的答案是:
答案 2 :(得分:-2)
答案是“声明可以进行多次,而定义只能进行一次”
为了清楚说明,只要在变量之前使用“extern”关键字,就意味着只是声明了变量。
extern int i = 5; - &GT;这只是声明一个变量
int i; ---&GT;定义并宣布