如果你有一个只使用'cout'对象的非常基本的C++程序,你可以在源文件中包含iostream,然后在编译它时你不必链接任何外部库.换句话说,你可以简单地运行
g++ main.cpp -c
g++ main.o -o program
./program
当您想要使用更复杂的对象(如线程)时,不仅包含pthread,而且在链接程序时必须链接到库.
g++ main.cpp -c
g++ main.o -lpthread -o program
./program
所以我的问题是,为什么我不必链接任何库来使用所有的iostream对象?
std::cout
在GCC自己的C++标准库中定义,该库g++
默认链接到它,它仅依赖于标准的CI/O工具,如FILE*
基本文件I/O,它们在默认情况下提供libc
,gcc
并且g++
也链接到.因此,您需要使用的所有内容都std::cout
默认链接到.
诸如pthread_create
不属于C++或C标准库的函数,它们在单独的库中定义libpthread
.GCC默认情况下该库没有链接,因为Pthreads不是语言的一部分(它由不同的标准定义,POSIX,而不是语言标准),也因为libpthread
无条件链接会使许多C++程序运行得更慢,因为原因解释如下.
GCC的C++标准库在许多地方使用引用计数(例如,在Copy-On-Write实现std::string
和中std::shared_ptr
),在多线程应用程序中,引用计数更新需要使用原子指令.在非多线程应用程序中,不需要原子操作,因此如果程序是单线程的,则libstdc ++使用普通的非原子更新.它检测程序是否多线程的方式是检查程序是否链接libpthread
.因此libpthread
,默认情况下链接到所有程序会导致库认为所有程序都是多线程的,并且总是使用较慢的原子操作,即使程序不使用任何线程也是如此.
因此,为避免使某些程序变慢,用户有责任libpthread
在需要时明确链接.
在POSIX平台上std::thread
是一个围绕Pthreads的瘦包装器,因此同样的规则适用于这种类型的功能pthread_create
:用户必须libpthread
手动链接.这是正确的,即使它std::thread
是语言标准的一部分,但因为它是在Pthreads之上实现的,并且由于上述性能影响,用户必须手动链接到它.
您链接时链接到库g++ main.o -o program
.默认情况下,一些库是自动链接的,唯一不链接它们的方法是传递-nodefaultlibs
(或等效).特别是,你会发现cout
在libstdc++
,这反过来使用libc
.这两个都默认链接.
如果已ldd
安装,则可以通过运行来验证ldd ./program
; 它会直接或间接地为您提供程序与之链接的所有库的列表.