There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin
. It sees that the argument is a constant expression, so it replaces the sin(...)
call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm
. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s
, the generated assembly language listing, you can see that there's no call to sin
.)
For the second example, you do need the -lm
option -- but it needs to be at the end of the command line, or at least after the file (useless.c
) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin
, referred to by useless.o
), and then resolving them as it sees their definitions. If you put the -lm
first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin
in useless.o
, it's too late.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…