【发布时间】:2014-03-17 15:53:29
【问题描述】:
在使用 Microsoft 编译器编译和链接 C 代码时,不同目标文件中具有相同名称的定义有多种可能的结果,具体取决于定义的类型。
int x[5] = {1};
int x[5] = {1};
两个初始化的数据定义;这是一个错误。
int x[5];
int x[10];
两个 BSS 定义。较大的获胜,较小的被丢弃,结果好像只有较大的定义存在。
int x[5] = {1};
int x[10];
一个初始化的数据定义和一个 BSS 定义。数据定义即使更小也会胜出,BSS 定义被丢弃。
我的问题是,如果除了初始化的数据定义是 COMDAT 之外,还有第三种情况的情况怎么办?即使更大,BSS 定义是否仍然被丢弃?还是取决于 COMDAT 选择字段,例如BSS 定义是否仅在 IMAGE_COMDAT_SELECT_LARGEST 情况下获胜,而数据定义在其他情况下获胜?
(我假设一个弱外部定义将被 BSS 定义覆盖,无论大小;如果不是这种情况,请纠正我。)
【问题讨论】:
-
这些只是源文件的静态吗?
-
那么为什么链接器会让你这样做呢?
-
@Rob 好吧,最终这是通常的历史原因加上向后兼容性;如果你现在从头开始定义语义,你就不会这样做。但我们并不是从头开始,C 和 PE 的语义就是它们的样子,我需要按它们的本来面目处理它们,而不是按我希望的那样处理它们。
标签: c windows visual-c++ linker portable-executable