两个静态库,两个不同的向量实现,链接器会做什么?

时间:2009-12-22 18:17:32

标签: c++ stl linker

想象一下,我们有两个使用std::vector的不同实现构建的静态库。这两个二进制文件都有push_backpop_back的代码(因为向量通常只是标题)。当我们尝试在项目中使用这两个库时,链接器会做什么。它会出错吗?链接器是否可以删除每个方法的一个实现,以便可以执行以下操作:

来自第二个库的

push_back调用从第一个库调用push_back实现

来自第一个库的

pop_back调用从第二个库调用pop_back实现

4 个答案:

答案 0 :(得分:3)

会出错吗?取决于你如何定义“错误”。

在链接时可能不会给你一个错误。但它肯定会破坏你的可执行文件。链接器在遇到符号的多个定义时假设它们是相同的,因此除了其中一个之外的其他所有都可以被丢弃。如果它们不相同,那么你违反了单一定义规则,这意味着你正在进入未定义的行为领域。什么都可能发生。最有可能的是,你会看到随机崩溃。

答案 1 :(得分:1)

编译系统为模板采用的最常见(但不是唯一)方法是编译器贪婪地实例化每个转换单元中使用的所有模板,从而导致多个实例化。然后链接器以静默方式丢弃重复项。

但是,我肯定不会依赖这种行为来处理同一(命名)模板的两种不同实现。

答案 2 :(得分:1)

最有可能的是,两种实现中的一种将被选择用于外部呼叫。

因为这里有很多陷阱我不会尝试这样做。这是一些问题:

  1. 创建对象时,调用它的位置会处理分配的字节数。因此,我们假设这两个实现使用不同的成员。如果选择的外部函数是假设更大的函数,则可能会破坏内存。
  2. 虽然将为外部调用选择两个实现中的一个,但编译器可能已经内联了一些其他方法。对于作为链接时间丢失的实现,其内联调用仍将存在于代码中,并且很可能是行为不端。

答案 3 :(得分:0)

根据链接者的心情,你最终会调用一个或另一个。一个糟糕的情况。