#include <math.h>
#include <stdio.h>
int main()
{
printf("%f", roundf(3.14));
}
I compile above code (hasn't use -lm), add use ldd a.out, the result is
linux-vdso.so.1 => (0x00007fffab9ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd6da0f8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd6da4eb000)
why a.out didn't link with libm but can use roundf (or something like sqrt)? I have use nm to test libc.so.6 and ld-linux-x86064.so.2 but all of this didn't have the symbol of roundf.
I want to know where roundf defined, or it has be inlined by compiler? (test with gcc 4.7.3 and gcc 4.6.3)
The answer is http://fedoraproject.org/w/index.php?title=UnderstandingDSOLinkChange
As an optimization, the compiler would have computed the value at compile time and used a constant, so there is no call to roundf()
involved. You can verify this by seeing the generated code:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, %eax
fldl .LC1
fstpl 4(%esp)
movl %eax, (%esp)
call printf
leave
ret
You can see that there is no call to roundf()
in the generated assembly. (You can generate this with gcc -S filename.c
and read the generated filename.s
file).
You mentioned libstdc++
in a comment, which makes me suspect that the problem is that you're linking with g++
rather than with gcc
.
The gcc
command invokes the compiler and/or the linker. If you use it to compile a source file, it normally determines the language (and therefore which compiler front-end to use).
The g++
command is similar, but it's specialized for C++; if it invokes the linker, it passes arguments as needed to link libraries like libstdc++
that are required for C++.
For example, these two commands, which just compile without linking:
gcc -c foo.cpp
g++ -c foo.cpp
are (as far as I know) equivalent, but these commands:
gcc foo.cpp -o foo
g++ foo.cpp -o foo
are not; the former will probably fail (depending on what features foo.cpp
uses).
And it turns out that the g++
command, unlike the gcc
command, implicitly links the math library, at least in the version on my system. So if your C++ code uses both C++-specific features (like, say, <iostream>
) and math functions, then linking it with the gcc
command is likely to produce complaints about functions defined in both libstdc++
and libm
-- which is just what you're seeing.
If you link with the g++
command, that should solve the problem. You'll probably have to modify your Makefile
or equivalent, or whatever generates it.
(If this is the solution, you should probably add "c++" to the list of tags on your question.)
As for why you didn't run into this problem before, I can't tell. Some C (and/or C++) compilers will link the math library implicitly; the need to specify -lm
for other compilers is arguably a bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With