2015-06-02 199 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:哦,可能。 –

相關問題