如果你有一个只使用'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对象?
答案 0 :(得分:14)
当您与g++ main.o -o program
链接时,您正在链接到图书馆。默认情况下,一些库是自动链接的,不链接到它们的唯一方法是传递-nodefaultlibs
(或等效的)。特别是,您会在cout
中找到libstdc++
,libc
会使用ldd
。这两个都默认链接。
如果您安装了ldd ./program
,则可以通过运行{{1}}来验证这一点;它会直接或间接地为您提供程序与之链接的所有库的列表。
答案 1 :(得分:14)
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 ++标准库在许多地方使用引用计数(例如,在std::string
和std::shared_ptr
的Copy-On-Write实现中)和多线程应用程序中的引用计数更新需要使用原子指令。在非多线程应用程序中,不需要原子操作,因此如果程序是单线程的,则libstdc ++使用普通的非原子更新。它检测程序是否多线程的方式是检查程序是否链接到libpthread
。因此,默认情况下,为所有程序链接到libpthread
会导致库认为所有程序都是多线程的,并且总是使用较慢的原子操作,即使程序没有使用任何线程。
因此,为避免某些程序变慢,用户有责任在需要时明确链接到libpthread
。
在POSIX平台上std::thread
是Pthreads的瘦包装器,因此同样的规则适用于类型pthread_create
之类的功能:用户必须手动链接到libpthread
。即使std::thread
是语言标准的一部分,但这是正确的,但是因为它是在Pthreads之上实现的,并且由于上述性能影响,用户必须手动链接到它。
答案 2 :(得分:4)
在构建gcc和g ++时,您可以指定"默认库"链接。
在一些预先构建的发行版中,他们非常友好地为你做了-lstdc ++,而某些发行版并没有。