C - 不同文件中的全局定义变量显示外部链接,没有 extern 修饰符

问题描述

彻底糊涂了。我很沮丧,因为我认为准确了解作用域和链接的工作原理很重要,但我一直看到关于 extern 的信息相互矛盾,而且我的编译器/链接器与我所读到的内容相矛盾。>

----------main.c--------------

int int1;

void main()
{  int1=6;
   printf("\nMain - int1 = %4d",int1);
   blippy();
   printf("\nMain - int1 = %4d",int1);
   return;
}

-------------second.c-------------

int int1;

void blippy()
{ printf("\nSecond - int1 = %4d",int1);
  int1++;
  return ;
}

输出为:

Main - int1 =    6
Second - int1 =    6
Main - int1 =    7

就好像 int1 的两个实例都指向一个带有外部链接的变量。我希望编译器要么抛出多重定义错误,要么将它们视为静态的。我正在使用 Codeblocks,我不知道它是否在幕后做任何冒昧的事情。

解决方法

很大程度上由于历史原因,int int1; 既不是简单的声明也不是简单的定义。这是一个暂定定义。如果翻译单元(被编译的源文件,包括它包含的所有文件)中没有对 int1 的常规定义,并且整个程序中只有一个定义,则暂定定义将作为常规定义。

但是,如果您在多个翻译单元中有相同标识符的暂定定义(没有常规定义),则 C 标准不会定义该行为。一些编译器,包括最近的 GCC,允许多个暂定定义并允许链接器将它们合并为一个定义。从版本 10 开始,GCC 不再这样做,并允许链接器将它们视为多个定义,除非开关 -fcommon 另有要求。

您可以通过提供初始化程序 int int1;int int1 = 0; 变成常规定义。

一些附加信息是 herehere

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...