Почему g++ все еще требует -latomic

В 29.5. Атомные типы рабочего стандарта С++ Standard в ноябре 2014 года:

  • Существует общий шаблонный шаблон. Тип аргумента шаблона T должен быть тривиально скопируемым (3.9). [Примечание. Невозможно использовать аргументы типа, которые также не могут быть статически инициализированы. -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();
}

должен быть вполне допустимым стандартным кодом С++ 14 (а также С++ 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 по-прежнему необходимо, или это просто то, что еще не было обработано сторонними компиляторами?

Ответ 1

Соответствующие чтения на главной странице GCC о том, как и почему GCC делает вызовы библиотеки в определенных случаях в отношении <atomic> в первую очередь.

GCC и libstdС++ только связаны друг с другом. libatomic является доменом библиотеки, а не компилятором, и вы можете использовать GCC с другой библиотекой (которая может предоставить необходимые определения для <atomic> в ее основном правиле или под другим именем), поэтому GCC не может просто предположим -latomic.

Также:

GCC 4.7 не включает реализацию библиотеки, поскольку API не был прочно установлен.

На той же странице утверждается, что GCC 4.8 предоставляет такую ​​библиотечную реализацию, но планы являются первыми жертвами войны. Я предполагаю, что причина для -latomic, которая по-прежнему необходима, может быть найдена в этой окрестности.

Кроме того,...

... до сих пор я думал, что любой стандартный сопоставимый код одного файла может быть скомпилирован с помощью первой команды.

... -lm существует довольно давно, если вы используете математические функции.

Ответ 2

Я знаю, что стандарт ничего не говорит о флажках или библиотеках компилятора, которые должны быть включены

Right.

но до сих пор я думал, что любой стандартный сопоставимый код одного файла может быть скомпилирован с помощью первой команды.

Ну, нет. Как вы только что сказали, нет особых оснований предполагать это. Также подумайте, что расширения GCC включены по умолчанию.

При этом кажется очевидным, что намерение состоит в том, чтобы сделать -latomic частью по умолчанию для среды выполнения, когда она немного успокоилась.

Ответ 3

g++ - это оболочка для gcc, которая добавляет правильные библиотеки С++. Очевидно, что в этом списке отсутствует -latomic. Не проблема основного компилятора, а просто небольшая ошибка в обертке.