为什么Borland在不同的C文件中使用相同对象的多个定义进行编译,而GCC没有?

我正在研究全局变量的行为。

到目前为止,我认为全局变量的多重定义是非法的方式,必须得到一个错误。 但是我从Borland C / C ++编译器得到了意想不到的结果,而GCC给了我预期的结果。

码:

test1.c

 #include void func(void); int num=1; void main(){ func(); return; } 

test2.c

 #include int num=2; void func(){ printf("%d",num); return; } 

在MS-DOS提示符下

  • Borland C / C ++:

     c:\test>bcc32 test1.c test2.c 
  • GCC:

     c:\test>gcc test1.c test2.c 

结果

  • Borland C / C ++:

没有错误并且编译和链接成功(对我来说这是意料之外的。)执行test1.exe ,控制台上打印出2。 这是test2.c定义的num的值。

  • GCC:

GCC给了我一个num的多重定义错误。 当然,没有制作一个。(这是我所期待的)

为什么会这样? 请告诉我。 谢谢!

对象的多个外部定义是C中的未定义行为。一个常见的扩展是接受多个定义(如果它们没有不同意(通常具有相同类型且没有初始化值)。

C99 6.9p5说:

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

和C99,4.p2:

在约束之外违反“应”意味着UB