Finally, there's an additional and big difference in link semantics between dynamic
linking and static linking that often confuses the unwary. Archives (static libraries) are
acted upon differently than are shared objects (dynamic libraries). With dynamic
libraries, all the library symbols go into the virtual address space of the output file,
and all the symbols are available to all the other files in the link. In contrast, static
linking only looks through the archive for the undefined symbols presently known to
the loader at the time the archive is processed.
A simpler way of putting this is to say that the order of the statically linked libraries
on the compiler command line is significant. The linker is fussy about where libraries
are mentioned, and in what order, since symbols are resolved looking from left to
right. This makes a difference if the same symbol is defined differently in two
different libraries. If you're doing this deliberately, you probably know enough not to
need to be reminded of the perils.
Another problem occurs if you mention the static libraries before your own code.
There won't be any undefined symbols yet, so nothing will be extracted. Then, when
your object file is processed by the linker, all its library references will be unfulfilled!
Although the convention has been the same since UNIX started, many people find it
unexpected; very few commands demand their arguments in a particular order, and
those that do usually complain about it directly if you get it wrong. All novices have
trouble with this aspect of linking until the concept is explained. Then they just have
trouble with the concept itself.
The problem most frequently shows up when someone links with the math library.
The math library is heavily used in many benchmarks and applications, so we want to
squeeze the last nanosecond of runtime performance out of it. As a result, libm has
often been a statically linked archive. So if you have a program that uses some math
routines such as the sin() function, and you link statically like this:
cc -lm main.c
you will get an error message like this:
Undefined first referenced
symbol in file
sin main.o
ld: fatal: Symbol referencing errors. No output
written to a.out
In order for the symbols to get extracted from the math library, you need to put the file containing the
unresolved references first, like so:
cc main.c -lm
This causes no end of angst for the unwary. Everyone is used to the general command form of