让我们假设我有一个库somelib.a
,它由程序包管理器以二进制形式分发。而且该库仅使用标头库anotherlib.hpp
。
如果我现在将程序链接到somelib.a
,并且还使用anotherlib.hpp
但版本不同,则如果somelib.a
使用{{1 }}在其anotherlib.hpp
标头中。
但是,如果include
仅在其cpp文件中引用/使用somelib.a
(会导致我不知道它使用它们),会发生什么?我的应用程序和anotherlib.hpp
之间的链接步骤是否可以确保somelib.a
和我的应用程序都使用自己的somelib.a
版本。
我问的原因是,如果我将程序的各个编译单元链接到最终程序,则链接器将删除重复的符号(取决于它是否是内部链接)。因此,通常只写头文件库的方式就可以删除重复的符号。
一个简单的示例
anotherlib.hpp
构建在具有nlohmann / json.hpp 3.2版的系统上
somelib / somelib.h
somelib.a
somelib.cpp
namespace somelib {
struct config {
// some members
};
config read_configuration(const std::string &path);
}
应用程序是在另一个具有nlohmann / json.hpp版本3.5和3.2和3.5的系统上构建的,然后将应用程序与在版本3.2的系统上构建的#include <nlohmann/json.hpp>
namespace somelib {
config read_configuration(const std::string &path)
{
nlohmann::json j;
std::ifstream i(path);
i >> j;
config c;
// populate c based on j
return c;
}
}
进行链接
application.cpp
somelib.a
答案 0 :(得分:4)
使用静态库几乎没有什么不同。
C ++标准规定,如果在程序中,内联函数(或类模板或变量等)有多个定义,并且所有定义都不相同,则您拥有UB。
实际上,这意味着除非头文件库的两个版本之间的更改非常有限,否则您将拥有UB。 例如,如果唯一的更改是空格更改,注释或添加新符号,那么您将不会有未定义的行为。但是,如果更改了现有函数中的单行代码,则为UB。
来自C++17 final working draft (n4659.pdf):
6.2一定义规则
[...]
一个类类型可以有多个定义(第12条), 枚举类型(10.2),具有外部链接的内联函数 (10.1.6),带有外部链接的内联变量(10.1.6),类 模板(条款17),非静态功能模板(17.5.6),静态 类模板的数据成员(17.5.1.3),类的成员函数 模板(17.5.1.1),或某些模板专门化 如果每个定义出现在不同的翻译单元中,并且前提条件满足以下定义,则在程序中未指定模板参数: 以下要求。
给出这样一个名为D的实体,该实体在多个翻译中定义 单位,然后
- D的每个定义中的
D的每个定义均应包含相同的内容 令牌顺序;和
- D的每个定义中的
根据6.4查找的名称,应指定义的实体 在D的定义之内,或者在指代同一实体之后 重载分辨率(16.3)和部分模板匹配后 专业化(17.8.3),只是名称可以引用(6.2.1)
具有内部链接或不具有链接的非易失性const对象,如果该对象
在D的所有定义中,
具有相同的文字类型, (6.2.1.2)
用常量表达式(8.20)初始化
在D的任何定义中均未使用,并且
在D的所有定义中具有相同的值,
或
- 内部链接或无链接的引用都用常量表达式初始化 这样,引用在所有定义中都指代同一实体 的D;和(6.3)
- 每个定义中的
,对应的实体 应当具有相同的语言联系;和
D,所指的重载运算符,对的隐式调用 转换函数,构造函数,运算符新函数和 操作员删除功能,应指相同的功能,或指 在D的定义内定义的功能;和
在每个定义中 D,(隐式或显式)函数调用使用的默认参数 视为其令牌序列出现在的定义中 D;也就是说,默认参数取决于要求 在本段中进行了说明(如果默认参数包含 具有默认参数的子表达式,此要求适用 递归).28
如果D是具有隐式声明的类 构造函数(15.1),就好像该构造函数是隐式定义的 在奇数个使用的翻译单元中,以及隐式 每个翻译单元中的定义应调用相同的构造函数 D的子对象。
如果D是模板并且在多个翻译单元中定义, 那么前述要求应同时适用于来自 模板定义(17.6.3)中使用的模板的封闭范围, 以及实例化时的从属名称(17.6.2)。如果 D的定义满足所有这些要求,那么行为 好像有一个D的定义。如果D的定义 不满足这些要求,则行为是不确定的。