在C ++标准2014年11月工作草案的 29.5原子类型中指出:
- 有一个泛型类模板atomic。模板参数T的类型应该是可以轻易复制的(3.9)。 [注意:不能静态初始化的类型参数可能难以使用。 - 尾注]
醇>
所以 - 据我所知 - 这:
#include <atomic>
struct Message {
unsigned long int a;
unsigned long int b;
};
std::atomic<Message> sharedState;
int main() {
Message tmp{1,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
仍然是必要的,或者它只是编译器维护者没有解决的问题呢?
答案 0 :(得分:5)
Relevant reading关于GCC在某些情况下首先就<atomic>
进行图书馆调用的方式和原因。
GCC和libstdc ++只是失去了耦合。 libatomic
是库的域,而不是编译器 - 您可以将GCC与不同的库一起使用(可能在其主要版本中提供<atomic>
的必要定义,或者使用不同的名称) ,因此GCC不能只是假设 -latomic
。
Also:
GCC 4.7不包含库实现,因为API尚未确定。
同一页声称GCC 4.8应提供此类图书馆实施,但计划是战争的第一个受害者。我猜在那附近可以找到-latomic
仍然有必要的原因。
...除了
如果您正在使用数学函数,...到目前为止,我认为可以通过第一个命令编译任何符合标准的单个文件代码。
... -lm
已存在很长时间了。
答案 1 :(得分:1)
我知道标准没有说明必须包含的编译器标志或库
右。
但到目前为止,我认为可以通过第一个命令编译任何符合标准的单个文件代码。
嗯,不。正如你只是所说,没有特别的理由去假设这一点。还要考虑默认情况下启用GCC扩展。
话虽这么说,似乎不言自明的是,当-latomic
在运行时稍微稳定下来时,它会成为运行时的默认部分。
答案 2 :(得分:0)
g++
是gcc
的包装器,它添加了正确的C ++库。显然,该列表中缺少-latomic
。那不是核心编译器问题,只是包装器中的一个小错误。