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

Why does g++ still require -latomic

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

  1. There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use. —end note ]

所以 - 据我所知 - 这个:

#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)代码。但是,如果我不手动 link libatomic,命令

g++ -std=c++14 <filename>

给出 - 至少在 Fedora 22 (gcc 5.1) 上 - 以下 linking 错误:

/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 仍然是必要的,是否有合理的理由,或者它只是编译器维护者尚未解决的问题?

g++gcc 的包装器,它添加了正确的 C++ 库。显然 -latomic 不在该列表中。那么不是核心编译器问题,只是包装器中的一个小错误。

Relevant reading 在 GCC 主页上关于 GCC 如何以及为什么在某些情况下首先调用关于 <atomic> 的库。

GCC 和 libstdc++ 只是松耦合。 libatomic 是库的域,而不是编译器——您可以将 GCC 与不同的库一起使用(它可能在其主要部分或不同的名称下为 <atomic> 提供必要的定义) , 所以 GCC 不能只是 assume -latomic.

Also:

GCC 4.7 does not include a library implementation as the API has not been firmly established.

同一页声称 GCC 4.8 应提供这样的库实现,但计划是 war 的第一个受害者。我想 -latomic 仍然需要的原因可以在附近找到。

此外...

...so far I thought that any standard conformant, single file code can be compiled via the first command.

如果您使用数学函数,

...-lm 已经存在了很长一段时间。

I know that the standard doesn't say anything about compiler flags or libraries that have to be included

没错。

but so far I thought that any standard conformant, single file code can be compiled via the first command.

嗯,不。正如您 just 所说,没有特别的理由假设这一点。还要考虑默认情况下启用 GCC 扩展。

话虽这么说,但似乎不言而喻的是,当 -latomic 稳定下来后,它会成为运行时的默认部分。