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

Why does g++ still require -latomic

本文关键字:atom g++ 为什么      更新时间:2023-10-16

29.5原子类型 c++标准2014年11月工作草案中声明:

    有一个泛型类模板原子。模板实参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仍然是必要的,或者它只是编译器维护者还没有解决的问题?

GCC主页上关于GCC如何以及为什么在某些情况下首先调用<atomic>的相关阅读

GCC和libstdc++只是松耦合的。libatomic是库的域,而不是编译器的域——并且您可以将GCC与不同的库一起使用(它可能在其主适当中为<atomic>提供必要的定义,或者以不同的名称),因此GCC不能仅假定 -latomic。也

:

GCC 4.7不包含库实现,因为API尚未牢固建立。

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

除了…

…到目前为止,我认为任何符合标准的单文件代码都可以通过第一个命令编译。

-lm已经存在很长一段时间了,如果你使用的是数学函数。

我知道标准没有说任何编译器标志或必须包含的库

.

但是到目前为止,我认为任何符合标准的单文件代码都可以通过第一个命令编译。

嗯,没有。正如你刚才所说,没有特别的理由来假设这一点。还要考虑GCC扩展在默认情况下是启用的。

话虽如此,似乎不言自明的意图是使-latomic成为运行时的默认部分,当它解决了一点。

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