There isn't really anything different between "system libraries" like iostream
and user-provided libraries except that the compiler will (as a convenience) leave some things implicit when dealing with the system libraries. In this case, it implicitly links to its default standard library implementation.
To expand on that, let's look at your first invocation of g++
:
g++ main.cpp
Since g++
's default standard library implementation is called libstdc++
, you could imagine that this is shorthand for:
g++ -lstdc++ main.cpp
(There may actually be more trickery involved, so I make no guarantees this expanded command will work as-is.)
And just in case you're not familiar with linking yet...
When you compile a .cpp
, the compiler produces an object file (often ending in .o
). When you have multiple .cpp
files, each one is compiled to a separate object file. Then they have to be merged somehow to produce the final executable. This merging is called linking and is done by a linker. The linker's job is basically to match names in different object files and output an executable file.
Except, that's too much of a simplification. The final result does not need to be an executable, it can also be a library. (I'll stick with static libraries for now, because I think it's simpler) A library is a file name according to this pattern: lib*.a
. Libraries cannot be executed. Instead, a library is just a convenient way to package up a bunch of functionality from many .cpp
into a form that is easy to consume later. You can link a library with your own object files to produce an executable with functionality from the library as well as your own code.
In the example of libstdc++, if we assume your system has a static library for it, that would be a file called libstdc++.a
. When linking, we strip the leading lib
and trailing .a
(because all libraries will have this) and just write stdc++
. This is why we would pass -lstdc++
to g++
.
The one problem (if I can call it that) with libraries is that they don't mean anything to the compiler, only to the linker. In order to use a library, your source code needs to #include
the corresponding header file so that the compiler can see the definitions/declarations in it.