为什么g ++仍然需要-latomic

时间:2015-06-02 08:44:04

标签: c++ c++11 g++ libstdc++ stdatomic

在C ++标准2014年11月工作草案的 29.5原子类型中指出:

  
      
  1. 有一个泛型类模板atomic。模板参数T的类型应该是可以轻易复制的(3.9)。 [注意:不能静态初始化的类型参数可能难以使用。 - 尾注]
  2.   

所以 - 据我所知 - 这:

#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仍然是必要的,或者它只是编译器维护者没有解决的问题呢?

3 个答案:

答案 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。那不是核心编译器问题,只是包装器中的一个小错误。