c++ - 模板实例化——编译器如何避免重复符号?

标签 c++ macos templates clang

假设我有一个人为设计的头文件,其中包含一个模板类和两个包含完全相同的模板类实例化的源文件,以及一个重复的函数。那就是……

人为的 header (thing.hpp):

#pragma once

template <typename T>
class Thing {
  public:
    T t;
  public:
    T& value() {
        return t;
    }
};

事物.cpp:

#include <thing.hpp>

template class Thing<int>;

int MeaningOfLife() {
    return 42;
}

thingy.cpp: (和thing.cpp一模一样)

在编译和链接时(在 OS X 上使用 clang),似乎只有 MeaningOfLife 被视为重复符号,但模板实例化的符号(这只是 Thing: :value()) 不是。仔细检查反汇编后,似乎在 Thing::value() 的符号上放置了一个名为 .weak_definition 的汇编指令。

问题 0: 这意味着该指令正在做一些事情来防止符号被多重定义,但它到底在做什么?

问题 1:其他编译器如何在其他地方(例如 Linux、Windows 等)完成此操作?

问题 2:如果我不正当更改其中一个重复模板实例化的汇编代码怎么办?即相同的符号,不同的函数体。智能编译器会检测到差异吗?

最佳答案

粗略的谷歌搜索将我们带到 these OSX docs ,其中指出:

The .weak_definition directive causes symbol_name to be a weak definition. symbol_name can be defined only in a coalesced section. This is used by the C++ compiler to support template instantiation. [...]

它继续定义 coalesced 因此:

A coalesced section can contain any instructions or data and is used when more than one definition of a symbol could be defined in multiple object files being linked together. The static link editor keeps the data associated with the coalesced symbol from the first object file it links and silently discards the data from other object files. An example of a coalesced section is one in which the compiler has generated code for implicit instantiations of C++ templates.

我不知道如果您修改其中一个定义会发生什么(我还没有尝试过),但是文档暗示链接器只是盲目地接受它首先找到的那个。

关于c++ - 模板实例化——编译器如何避免重复符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47489552/

相关文章:

c++ - 在循环中初始化结构/类的效率损失

c++ - 如何将抽象类指针作为 Q_PROPERTY?

C++ 模板类与其他模板方法的继承

c++ - 在非模板类中使用通用模板类

c++ - 卡片边缘检测 OpenCV

DLL 中的 C++ FindProcessWindow

swift - 如何编辑焦点文本字段? ( swift ,macOS)

networking - 如何在 OSX 上为 TUN 接口(interface)设置 IP 地址(没有目标地址)?

macos - 用户级别的 Haskell

c++ - 模板中的 Typedef 导致阴影模板参数错误