【发布时间】:2021-05-18 13:21:39
【问题描述】:
0.c
int i = 5;
int main(){
return i;
}
1.c
int i;
上面使用gcc 0.c 1.c 编译良好,没有关于multiple definitions 的任何链接错误。原因是i 生成为common blocks (-fcommon which is the default behaviour in gcc)。
正确的方法是使用此处缺少的 extern 关键字。
我一直在网上搜索这是否是未定义的行为,有些帖子说是,有些人说不是,这非常令人困惑:
是UB
Is having multiple tentative definitions in separate files undefined behaviour?
Why can I define a variable twice in C?
How do I use extern to share variables between source files?
http://port70.net/~nsz/c/c11/n1570.html#J.2
使用了具有外部链接的标识符,但在程序中不存在该标识符的确切一个外部定义,或者未使用该标识符并且该标识符存在多个外部定义(6.9)。
不是 UB
Global variables and the .data section
Defining an extern variable in multiple files in C
Does C have One Definition Rule like C++?
Look for -fno-common:
https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Code-Gen-Options.html
那么它是哪一个?使用-fcommon 是少数几个允许使用multiple definition 并且编译器会为您解决的地方之一?还是还是UB?
【问题讨论】:
-
根据标准这是未定义的,但在 gcc 上定义了实现。这不是唯一一个由于扩展而导致未定义的“工作”的例子。
-
答案stackoverflow.com/questions/67270121/… 解释:
.... If a program disobeys this rule, the C standard does not define the behavior (C 2018 4 2). Instead, we let the compiler and the linker define the behavior.和整个段落。 -
尝试用
gcc 0.c 1.c -pedantic-errors -Wall -Wextra重新编译,如果这是一个扩展,它可能会给你一个错误/警告。 (未测试) -
不管怎样,MSVC 的链接和 LLVM 的 lld 都无法链接并引发重复符号错误。当没有使用 -extern 引用非静态全局变量时,Clang 也会发出警告。
-
恭喜你提出了很好的问题。
标签: c