为什么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