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С++ для вас, в некотором дистрибутиве нет.