Why it didn't need link libm?
Asked Answered
O

2

5
#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

Osteoclasis answered 25/4, 2013 at 0:25 Comment(3)
These are present in libc IIRC.Redskin
Is IIRC stand for cross-tools ??Osteoclasis
IIRC = "if I recall correctly"Untold
A
7

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).

Abbyabbye answered 25/4, 2013 at 0:29 Comment(4)
Oh, I'm so stupid.- But the original problem is I have some project be compiled OK with gcc 4.6.3 but when I update my system (Deepin, An Chinese distribution based on Ubuntu) many project can't successful compile. The gcc report can't find roundf and tell me link these libraries manually. (Have many undefined function) I can't understand why.Osteoclasis
@snyh: I suggest you post a new question about that problem, using a demo program that doesn't let gcc optimize the call. I'm surprised that you wouldn't have needed to use -lm with gcc 4.6.3. But adding -lm should fix the problem (assuming all the functions it's complaining about are math functions).Cathryncathy
@KeithThompson Sorry, but I can't constructor a simple demo code. The one project is webkitgtk-1.8.2 and the other is DDE(an new linux desktop environment). The DDE's code and cmake file is my write so I can sure I didn't link libm before, and it can compile OK at least three month. But now I must link with libm explicitly.- I want to know is there some trick in gcc. Or is there has some default link libraries?- It didn't only report libm but also libstdc++ in webkitgtk.Osteoclasis
Did you / your build system run ./configure on every package before attempting to compile? Or does it use a previously created config?Abbyabbye
C
1

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.

Cathryncathy answered 25/4, 2013 at 1:16 Comment(1)
I found the key is "The default behaviour for ld allows users to 'indirectly' link to required objects/libraries through intermediate objects/libraries." ([link]fedoraproject.org/w/index.php?title=UnderstandingDSOLinkChange), but now it can't :(Osteoclasis

© 2022 - 2024 — McMap. All rights reserved.