错误:’i’的extern声明遵循声明而没有链接

在下面的程序中,我认为extern int i; 将更改以下i以引用i定义的外部main

 #include  extern int i=1; // warning: 'i' initialized and declared 'extern' int main() { int i=2; printf("%d\n", i); extern int i; // error: extern declaration of 'i' follows declaration with no linkage printf("%d\n", i); return 0; } 

“错误:’i’的外部声明遵循没有链接的声明”的原因是什么,其中“没有链接的声明”是指int i=2;

main删除int i=2后,

  • 错误消失了,
  • extern int i=1;上的警告“警告:’我’初始化并声明’extern’” extern int i=1; 也消失了。 这是为什么?

谢谢你的解释!

main函数中定义名为i的变量后,文件范围内的i被屏蔽并且无法访问(除非您有其地址)。

当您稍后添加声明extern int i ,这会与同一范围内名为i的局部变量冲突,因为locals不能具有外部链接。 它不会让您访问全局i

删除本地iextern int i声明与文件范围的定义匹配,因此没有错误。 至于extern int i=1;的警告extern int i=1; ,这对gcc 4.1.2并没有消失,所以这取决于编译器。

 #include  int i=1; // external variable int main() { int i=2; // local variable printf("%d\n", i); // print local variable i==2 { extern int i; // point to external variable printf("%d\n", i); // print external variable i==1 } return 0; } 

问题:“错误的原因是什么:’i’的外部声明遵循没有链接的声明”,其中“没有链接的声明”是指int i = 2;?
答:当它是程序中的单个文件时,我们不需要在第3行使用extern关键字,并且在同一程序中没有其他文件或者在变量int i具有其定义的同一文件中的其他位置。 我们可以在C中使用extern关键字有两个主要原因:
1.当我们想要显式地/全局地声明变量但没有它的定义时。
2.使变量从多文件程序中的任何其他文件或同一文件的其他位置全局可见(有关此方案,请参阅Ihdina的例子)。
在我的系统上编译代码我收到以下错误,
错误:’i’的extern声明遵循非extern声明 。 完全有意义的是编译器在第9行检测到extern作为第7行上相同变量int i的重复声明。

问题:在main中删除int i = 2之后,错误消失,警告“警告:’我’初始化并在extern int i = 1上声明’extern’”; 也消失了。 这是为什么?
答:删除int i = 2后; 错误在我的系统上消失了,但我仍然有以下警告消息:
警告:’extern’变量有一个初始值设定项[-Wextern-initializer]基本上我的系统( Apple LLVM版本8.1.0(clang-802.0.42) )不喜欢用extern关键字显式初始化。 因此,您应该根据Ihdina的答案修改您的代码,该答案可以无错误地编译。