【发布时间】:2023-03-20 06:40:01
【问题描述】:
我有一段极其琐碎的 C 代码:
static int arr[];
int main(void) {
*arr = 4;
return 0;
}
我知道第一条语句是非法的(我已经声明了一个具有静态存储持续时间和文件链接但没有指定大小的文件范围数组),但为什么会导致链接器错误? :
/usr/bin/ld: /tmp/cch9lPwA.o: in function `main':
unit.c:(.text+0xd): undefined reference to `arr'
collect2: error: ld returned 1 exit status
编译器不应该能够在链接器之前捕捉到这个吗?
我也很奇怪,如果我省略了 static 存储类,编译器只是假设数组的长度为 1 并且除此之外不会产生任何错误:
int arr[];
int main(void) {
*arr = 4;
return 0;
}
结果:
unit.c:5:5: warning: array 'arr' assumed to have one element
int arr[];
为什么在这里省略存储类会导致不同的行为,为什么第一段代码会产生链接器错误?谢谢。
【问题讨论】:
-
废话代码 - 废话信息
-
有趣的事实:它用 clang 编译,但不是 gcc。
-
我对 clang 的行为感到惊讶 6.9.2p3 “如果对象标识符的声明是一个暂定定义并且具有内部链接,则声明的类型不应是不完整的类型。”
-
静态定义的版本使用
gcc -pedantic编译失败。