G++ почему вам не нужно связывать бинарные файлы iostream, но для pthread вы делаете?
Если у вас есть очень простая программа на С++, которая использует объект 'cout', вы можете включить iostream в исходный файл, а затем, когда вы его скомпилируете, вам не нужно связывать любые внешние библиотеки. Другими словами, вы можете просто запустить
g++ main.cpp -c
g++ main.o -o program
./program
Если вы хотите использовать более сложные объекты, такие как потоки, вы не только включаете pthread, но и когда вы связываете программу, вы должны ссылаться на библиотеку.
g++ main.cpp -c
g++ main.o -lpthread -o program
./program
Итак, мой вопрос: почему мне не нужно связывать любые библиотеки для использования всех объектов iostream?
Ответы
Ответ 1
Вы связываетесь с библиотеками, когда вы связываетесь с g++ main.o -o program
. Некоторые библиотеки автоматически связаны по умолчанию, и единственный способ не ссылаться на них - передать -nodefaultlibs
(или эквивалент). В частности, вы найдете cout
в libstdc++
, который, в свою очередь, использует libc
. Оба из них связаны по умолчанию.
Если у вас установлен ldd
, вы можете проверить это, запустив ldd ./program
; он предоставит вам список всех библиотек, с которыми связана ваша программа, прямо или косвенно.
Ответ 2
std::cout
определяется в стандартной библиотеке CCC CCC, к которой по умолчанию привязаны g++
ссылки, и это зависит только от стандартных возможностей CI/O, таких как FILE*
и базовых файлов ввода/вывода, которые приведены в libc
, к которому по умолчанию привязаны gcc
и g++
. Итак, все, что вам нужно использовать std::cout
, связано по умолчанию.
Функции, такие как pthread_create
, не являются частью стандартных библиотек С++ или C, они определены в отдельной библиотеке libpthread
. Эта библиотека не связана по умолчанию с GCC, потому что Pthreads не является частью языка (он определяется другим стандартом, POSIX, но не языковыми стандартами), а также потому, что ссылка на libpthread
безусловно, заставит многие программы на С++ работать медленнее по причинам, описанным ниже.
Стандартная библиотека GCC С++ использует подсчет ссылок в нескольких местах (например, в реализации копирования std::string
и std::shared_ptr
), а в многопоточных приложениях обновления ссылок на ссылки должны использовать атомарные инструкции. В не многопоточных приложениях атомарные операции не нужны, поэтому libstdС++ использует обычные, неатомные обновления, если программа однопоточная. Способ определения того, является ли программа многопотоковой или нет, проверяя, связана ли программа с libpthread
или нет. Таким образом, привязка к libpthread
для всех программ по умолчанию заставит библиотеку думать, что все программы многопоточны и всегда используют более медленные атомные операции, даже если программа не использует нити.
Таким образом, чтобы избежать замедления работы некоторых программ, пользователю необходимо явно ссылаться на libpthread
, когда это необходимо.
На платформах POSIX std::thread
- тонкая оболочка вокруг Pthreads, поэтому для этого типа применяется такое же правило, как и для таких функций, как pthread_create
: пользователь должен ссылаться на libpthread
вручную. Это правда, даже если std::thread
является частью стандартного языка, но поскольку он реализован поверх Pthreads и из-за последствий производительности, описанных выше, пользователь должен ссылаться на него вручную.
Ответ 3
при построении gcc и g++ вы можете указать "библиотеки по умолчанию" для связи с.
В некотором заранее построенном дистрибутиве они достаточно любезны, чтобы делать -lstdС++ для вас, в некотором дистрибутиве нет.