g++ why don't you have to link iostream binaries but for pthread you do?
Asked Answered
P

3

13

If you have a very basic C++ program that only uses the 'cout' object, you can include iostream in the source file and then when you compile it you don't have to link any external libraries. In other words, you can simply run

g++ main.cpp -c

g++ main.o -o program

./program

When you want to use more complicated objects such as threads, not only do you include pthread, but when you link the program you have to link to a library.

g++ main.cpp -c

g++ main.o -lpthread -o program

./program

So my question is, why didn't I have to link any libraries to use all the iostream objects?

Picardi answered 30/7, 2014 at 12:9 Comment(3)
One is a standard library and the other is a posix (p)thread library.Habitude
BTW, the correct flag is -pthread for both linking and compiling. When compiling it defines _REENTRANT macro, when linking it links the necessary libraries.Frank
To be clear, is your program using the standard threading library (in which case you need -pthread not -lpthread, and the answer is complicated), or is it using pthreads directly (in which case the answer is that GCC only links with the standard C++ library by default)?Poddy
Z
14

You are linking to libraries when you link with g++ main.o -o program. A few libraries are auto-linked by default, and the only way to not link to them is to pass -nodefaultlibs (or equivalent). In particular, you'll find cout in libstdc++, which in turn uses libc. Both of those are linked by default.

If you have ldd installed, you can verify this by running ldd ./program; it will give you a list of all libraries your program has linked with, directly or indirectly.

Zinciferous answered 30/7, 2014 at 12:13 Comment(0)
H
14

std::cout is defined in GCC's own C++ standard library, which g++ links to by default, and it only depends on standard C I/O facilities such as FILE* and basic file I/O, which are provided in libc, which gcc and g++ also link to by default. So everything you need to use std::cout is linked to by default.

Functions such as pthread_create are not part of the C++ or C standard libraries, they are defined in the separate library libpthread. That library is not linked to by default by GCC, because Pthreads is not part of the language (it's defined by a different standard, POSIX, but not the language standards) and also because linking to libpthread unconditionally would make many C++ programs run slower, for reasons explained below.

GCC's C++ standard library uses reference counting in a number of places (e.g. in the Copy-On-Write implementation of std::string and in std::shared_ptr) and in multithreaded applications the reference count updates need to use atomic instructions. In non-multithreaded applications the atomic operations are not needed, so libstdc++ uses normal, non-atomic updates if the program is single-threaded. The way it detects whether the program multithreaded or not is by checking whether the program is linked to libpthread or not. So linking to libpthread for all programs by default would cause the library to think all programs are multithreaded, and to always use the slower atomic operations, even when the program doesn't use any threads.

So to avoid making some programs slower it is the user's responsibility to link to libpthread explicitly when required.

On POSIX platforms std::thread is a thin wrapper around Pthreads, so the same rule applies for that type as for the functions like pthread_create: the user must link to libpthread manually. That's true even though std::thread is part of the language standard, but because it's implemented on top of Pthreads and because of the performance implications described above, the user must link to it manually.

Hispania answered 30/7, 2014 at 12:21 Comment(3)
Does it mean that std::string reference counter updates are not inlined, since it detects the multi-threaded case at link time only?Frank
@MaximYegorushkin, they are still inlined. They are indirected through functions which then dispatch to atomic or non-atomic implementations based on a run-time check to see if libpthread is linked in (by checking if pthread_create is a weak symbol or not). The result of that check is cached in a local static and re-used on subsequent calls.Hispania
Note that with the GCC 5 ABI, std::string is no longer CoW.Quip
M
4

when building gcc and g++ you may specify "default libraries" to link with.

In some pre-built distribution they are kind enough to do -lstdc++ for you, some distribution don't.

Milkandwater answered 30/7, 2014 at 12:14 Comment(3)
That's not dependent on the distribution, but on whether you're linking with gcc or with g++. I suppose it's theoretically possible for a distro to remove that distinction, but I've never heard of any distro doing that.Zinciferous
If you build gcc yourself, you can specify a custom default libraries and link script; which is usually useful for building cross-compiler and with libc replacement.Milkandwater
I think it's safe to assume that someone asking why they don't need to link explicitly to the stdlib has not built GCC themselves and is using a typical setupHispania

© 2022 - 2024 — McMap. All rights reserved.