Billy Mays said:
http://c-faq.com/fp/libm.html
The answer to question 14.3 suggests linking against libm, "due to a
longstanding bug in Unix and Linux systems". Is there any elaboration
on what the bug is or where it came from? Is this solution portable?
The nature of the "bug" is that Unix compilers typically do not
load the math library by default, even if the program calls math
functions.
The C standard library is typically implemented in one or more
separate system libraries; the nature of the system libraries is
entirely implementation-defined. When you link your program, the
linker has to know which libraries to search to resolve function
calls in your program. Most of the C standard library is usually
in the set of system libraries that are searched by default, so
you don't need to specify them.
The choice of which system libraries to search by default, and
which to require the user to ask for, is largely an arbitrary one.
Since C is (perceived as) primarily a systems programming language,
and system-level programs typically don't need math functions, the
choice was made several decades ago *not* to load the system math
library unless the user specifically asks for it. This was not an
unreasonable decision at the time, when computers were slower and
searching the math library on every link operation could have been
a significant burden.
I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed. Implicitly searching
the math library should be relatively harmless; the extra time is
minimal, and if no math functions are actually called the library
won't actually be loaded (this may not have been the case for early
Unix linkers).
On the other hand, most C compilations are not done manually on the
command line, but are automated via Makefiles or something similar.
If Makefiles are to be somewhat portable, they'll have to specify
"-lm" explicitly, until all C implementations have "fixed" the
"bug". Most of them, for whatever reason, have shown little
interest in doing so, so we'll be stuck with the explicit "-lm"
for a long time to come.
As for whether it's portable: No. Using "-lm" is likely to be
portable to most or all Unix-like environments, including the various
flavors of Unix, Linux, Cygwin, and whatever other Unix-like things
are out there. Non-Unix-like systems are likely to have an entirely
different syntax for invoking the compiler and/or linker.
The C standard itself has nothing to say on the issue; it's (almost?)
entirely silent on the way in which a C compiler and/or linker is
invoked.