【问题标题】:COMDAT vs BSS definitionsCOMDAT 与 BSS 定义
【发布时间】: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


【解决方案1】:

根据 Microsoft 链接器的实验,COMDAT 初始化定义仍然有效,并且相应的 BSS 定义即使更大也会被丢弃。我不知道是否有任何外来标志会改变这个结果。

【讨论】:

    猜你喜欢
    • 2012-09-12
    • 2019-09-10
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多