14

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

  1. 有一个通用类模板原子。模板参数 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仍然是必要的,或者它只是编译器维护人员尚未解决的问题?

4

3 回答 3

5

GCC 主页上的相关阅读<atomic>内容,首先了解 GCC 在某些情况下如何以及为何进行库调用。

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

还有

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

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

除了...

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

...-lm如果您使用数学函数,它已经存在了很长一段时间。

于 2015-06-02T09:32:17.717 回答
1

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

正确的。

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

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

话虽这么说,似乎不言而喻,其意图是-latomic在运行时稍微稳定下来时将其作为默认部分。

于 2015-06-02T09:38:41.117 回答
-3

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

于 2015-06-02T09:20:07.227 回答