2015-06-02 146 views
10

29.5原子类型的C++标准2014年11月工作草案它指出:为什么G ++仍然需要-latomic

  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)代码。但是,如果我不手动链接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

Relevant reading在海湾合作委员会主页上介绍了GCC如何以及为什么在某些情况下首先对<atomic>进行库调用。

GCC和libstdC++只是失败耦合。 libatomic是库的领域,而不是编译器 - 你可以使用GCC与不同的库(它可以提供主要本身或不同名称的<atomic>的必要定义),所以GCC不能只是假定-latomic

Also

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

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

除了...

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

... -lm已经有相当长的一段时间,如果你使用的数学函数。

+2

请注意,C++标准在库是否是一个单独的组件方面有些模棱两可 - 库部分是相当独立的,但标准中的“实现”意味着编译器和库的组合。 – MSalters

+1

纠正我,如果我错了,但海湾合作委员会 - 默认情况下 - 包括几个库,那么默认的'-latomic'将如何不同? – MikeMB

+0

@ MSalters:是的,但在GCC的情况下,“执行”是指“GCC和一些兼容的标准库”。这就是我想要指出的 - 编译器和它的(n)个标准库之间尚未最终确定的API,并且你从编译器的人那里获得了一个单独的'-latomic',它们并不认为它所有这些问题都需要'-lm'作为数学代码。没有什么大不了的。 – DevSolar

0

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

+0

这可能是一个有意识的决定,因为它尚未完全实施。特别是* 29.3订单和一致性*支持列为“部分”。 https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2014 –

+4

'g ++'不是'gcc'的包装器。它们更像是兄弟姐妹,都包装了各种实际的编译器(例如'cc1plus')。 –

1

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.

那么,没有。正如你只是所说,没有什么特别的理由可以假设这一点。还要考虑到默认情况下启用GCC扩展。

话虽如此,似乎不言而喻,其目的是使-latomic运行时的默认部分,当它稍微安定下来。

+0

很明显,我没有根据标准中的任何内容做出这种假设,而是基于我对g ++的(有点有限的)经验。还纠正我,如果我错了,但不'-std = C++ 11'禁用g ++特定的扩展? – MikeMB

+0

@MikeMB:哦,可能。 –

相关问题