gpt4 book ai didi

多个弱符号的后果(C 链接器)

转载 作者:行者123 更新时间:2023-11-30 19:29:05 24 4
gpt4 key购买 nike

我只是对多个弱符号的潜在问题有疑问,这个问题来自我的教科书:

一个模块A:

int x;
int y;
p1() {...}

另一个模块B:
double x;
p2() {...}

我的教科书上说 '在 p2 中写入 x 可能会覆盖 y'
我可以理解教科书的想法(double x 是 int x 大小的两倍,int y 放在 int x 之后,问题来了),但仍然迷失了细节,我知道何时有多个弱符号,链接器只会随机选择一个,所以我的问题是,链接器选择的模块的哪个 x 将导致写入 p2 中的 x 将覆盖 y。

这是我的理解:如果链接器选择 模块 A 的 int x 将导致结果,因为这样 x,y 都是 4 个字节,而 p2(编译后的图像有一个汇编代码 movq 与 p1 中的 movl 进行比较)将更改 8 个字节,因此覆盖 y。

但是我的导师说如果只有链接器选择 模块 B 的双 x ,这将导致覆盖y,怎么会,我是正确的还是我的导师是正确的?

最佳答案

根据 ISO C,程序调用未定义的行为。使用的外部名称必须在程序中的某处具有完全相同的定义。*

“弱符号”是一些动态库系统中的一个概念,例如 GNU/Linux 上的 ELF。该术语不适用于此处。允许对外部符号进行多个定义的链接器据说正在实现“宽松的 ref/def”模型。该术语来自 ANSI C rationale 的第 6.1.2.2 节。 .

如果我们将宽松的 ref/def 模型视为文档化的语言扩展,那么名称的多个定义将成为本地定义的行为。但是,如果它们的类型不一致怎么办?几乎可以肯定的是,这种情况类似于坏类型别名的推理是不确定的。如果一个模块有 int x; int y;另一个有 double x , 那是通过 double x 写的别名将破坏 y .这不是您可以可移植依赖的东西。故意获得混叠效果是一种非常糟糕的方法;您想使用 union在两个结构或一些这样的结构之间。

现在关于“弱符号”:这些是共享库中的外部名称,可以被替代定义覆盖。例如,GNU/Linux 系统上的 GNU C 库中的大多数函数都是弱符号。程序可以定义自己的read例如,替换 POSIX 的函数。无论如何,图书馆本身都不会破坏read被重新定义;什么时候需要调用read , 它不使用弱符号 read但一些内部别名,如 __libc_read .
这种机制很重要;它允许库符合 ISO C。允许严格符合 ISO C 程序使用 read作为外部名称。

* 在 ISO C99 标准中,这是在 中给出的。 6.9 外部定义 :“如果在表达式中使用了通过外部链接声明的标识符(而不是作为结果为整数常量的 sizeof 运算符的操作数的一部分),则在整个程序的某处,该标识符应该只有一个外部定义;否则,不得超过一个。”

关于多个弱符号的后果(C 链接器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53255357/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com