为啥g ++仍然需要-latomic
Posted
技术标签:
【中文标题】为啥g ++仍然需要-latomic【英文标题】:Why does g++ still require -latomic为什么g ++仍然需要-latomic 【发布时间】:2015-08-15 23:08:24 【问题描述】:在 C++ 标准 2014 年 11 月工作草案的 29.5 原子类型中,它指出:
有一个通用类模板原子。模板参数 T 的类型应该是可简单复制的(3.9)。 [注意:不能静态初始化的类型参数可能难以使用。 ——尾注]
所以 - 据我所知 - 这个:
#include <atomic>
struct Message
unsigned long int a;
unsigned long int b;
;
std::atomic<Message> sharedState;
int main()
Message tmp1,2;
sharedState.store(tmp);
Message tmp2=sharedState.load();
应该是完全有效的标准 c++14(以及 c++11)代码。但是,如果我不手动链接libatomic
,则命令
g++ -std=c++14 <filename>
给出 - 至少在 Fedora 22 (gcc 5.1) - 以下链接错误:
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::store(Message, std::memory_order)':
main.cpp:(.text._ZNSt6atomicI7MessageE5storeES0_St12memory_order[_ZNSt6atomicI7MessageE5storeES0_St12memory_order]+0x3f): undefined reference to `__atomic_store_16'
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::load(std::memory_order) const':
main.cpp:(.text._ZNKSt6atomicI7MessageE4loadESt12memory_order[_ZNKSt6atomicI7MessageE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
如果我写
g++ -std=c++14 -latomic <filename>
一切都很好。 我知道标准没有说明必须包含的编译器标志或库,但到目前为止,我认为任何符合标准的单文件代码都可以通过第一个命令编译。
那么为什么这不适用于我的示例代码呢?为什么-latomic
仍然是必要的,是否有合理的理由,或者它只是编译器维护人员尚未解决的问题?
【问题讨论】:
【参考方案1】:Relevant reading 在 GCC 主页上,了解 GCC 在某些情况下如何以及为什么首先针对 <atomic>
进行库调用。
GCC 和 libstdc++ 只是松散耦合。 libatomic
是库的域,而不是编译器——您可以将 GCC 与不同的库一起使用(这可能会在其主要属性中或以不同的名称为 <atomic>
提供必要的定义),因此 GCC 不能只是假设 -latomic
。
Also:
GCC 4.7 不包含库实现,因为 API 尚未牢固建立。
同一页面声称 GCC 4.8 应提供这样的库实现,但计划是战争的第一个受害者。我猜想-latomic
仍然需要的原因可以在附近找到。
另外...
...到目前为止,我认为任何符合标准的单文件代码都可以通过第一个命令进行编译。
...-lm
如果您使用数学函数,它已经存在了很长一段时间。
【讨论】:
请注意,C++ 标准对于库是否是一个单独的组件有点含糊——库部分是相当独立的,但标准中的“实现”是指编译器和库的组合。 如果我错了,请纠正我,但 gcc 确实 - 默认情况下 - 包含几个库,那么默认-latomic
会有什么不同?
@MSalters:是的,但是对于 GCC,“实现”意味着“GCC 和一些兼容的标准库”。这就是我想指出的——编译器和它的 (n) 个标准库中的 一个 之间的一个尚未最终确定的 API,你会从编译器人员那里得到一个单独的 -latomic
也不认为数学代码需要-lm
有那么大的问题。没什么大不了的。
我好久没用gcc了,但是g++ -lm就没有必要了吧?
顺便说一句:您对 gcc 4.7 的引用是我问的原因,为什么在 GCC 5.1 中仍然需要它。【参考方案2】:
我知道标准没有说明必须包含的编译器标志或库
没错。
但到目前为止,我认为任何符合标准的单文件代码都可以通过第一个命令进行编译。
嗯,不。正如您刚刚所说,没有特别的理由可以假设这一点。还要考虑默认情况下启用 GCC 扩展。
话虽如此,其意图似乎是不言而喻的是,当-latomic
稍微稳定后,它会成为运行时的默认部分。
【讨论】:
显然我并没有根据标准中编写的任何内容做出这个假设,而是基于我对 g++ 的(有些有限的)经验。如果我错了也请纠正我,但-std=c++11
不会禁用 g++ 特定扩展吗?
@MikeMB:哦,可能会。【参考方案3】:
g++
是gcc
的包装器,它添加了正确的 C++ 库。显然,该列表中缺少 -latomic
。那么不是核心编译器问题,只是包装器中的一个小错误。
【讨论】:
这很可能是一个有意识的决定,因为它尚未完全实施。特别是29.3 顺序和一致性 支持被列为部分。 gcc.gnu.org/onlinedocs/libstdc++/manual/…g++
不是“gcc
的包装器”。它们更像是兄弟姐妹,都封装了各种实际的编译器(例如cc1plus
)。以上是关于为啥g ++仍然需要-latomic的主要内容,如果未能解决你的问题,请参考以下文章
为啥缓存的 Drools KIE 基础仍然需要源 .drl 文件?