8

From this question: Why do you have to link the math library in C?

I know that C math library (libm) is separated from C standard library (libc), and is not linked in by default.

But when I compiled the code below using gcc filename.c without -lm on mac osx 10.11.1 :

#include <math.h>
#include <stdio.h>

int
main (void)
{
  double x = sqrt (2.0);
  printf ("The square root of 2.0 is %f\n", x);
  return 0;
}

There's no link error and the output executable file works correctly.

Then I tried otool -L output:

output:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
    /opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

I wonder to know is there some library structure differences on mac?

Or it's the new feature for gcc 5.2.0?

Thanks a lot!

Update:

I changed the code with:

    double in = 0;
    scanf("%lf", &in);
    double x = sqrt(in);

and it still doesn't need -lm.

And I disassemble the code with otool -vVt:

(__TEXT,__text) section
_main:
0000000100000eed    pushq   %rbp
0000000100000eee    movq    %rsp, %rbp
0000000100000ef1    subq    $0x10, %rsp
0000000100000ef5    pxor    %xmm0, %xmm0
0000000100000ef9    movsd   %xmm0, -0x10(%rbp)
0000000100000efe    leaq    -0x10(%rbp), %rax
0000000100000f02    movq    %rax, %rsi
0000000100000f05    leaq    0x82(%rip), %rdi        ## literal pool for: "%lf"
0000000100000f0c    movl    $0x0, %eax
0000000100000f11    callq   0x100000f54             ## symbol stub for: _scanf
0000000100000f16    movq    -0x10(%rbp), %rax
0000000100000f1a    movd    %rax, %xmm0
0000000100000f1f    callq   0x100000f5a             ## symbol stub for: _sqrt
0000000100000f24    movd    %xmm0, %rax
0000000100000f29    movq    %rax, -0x8(%rbp)
0000000100000f2d    movq    -0x8(%rbp), %rax
0000000100000f31    movd    %rax, %xmm0
0000000100000f36    leaq    0x55(%rip), %rdi        ## literal pool for: "The square root of 2.0 is %f\n"
0000000100000f3d    movl    $0x1, %eax
0000000100000f42    callq   0x100000f4e             ## symbol stub for: _printf
0000000100000f47    movl    $0x0, %eax
0000000100000f4c    leave
0000000100000f4d    retq

It seems sqrt is called. So why things go different on mac?

Update:

I found the conclusion in this question: C std library don't appear to be linked in object file

It says on OS X, the math library is part of libSystem:

$ ls -l /usr/lib/libm.dylib
lrwxr-xr-x  1 root  wheel  15  3 Jun 01:39 /usr/lib/libm.dylib@ -> libSystem.dylib
Community
  • 1
  • 1
Daizy
  • 331
  • 2
  • 5
  • 12
  • 1
    Perhaps the compiler knows what `sqrt(2.0)` is (I do) and so it doesn't have to call the library. – Bo Persson Nov 12 '15 at 16:26
  • @BoPersson Maybe it's the real reason for that. Do you know some functions that cannot be optimized by compiler in C math library? I want to try it. Thanks a lot! – Daizy Nov 13 '15 at 13:28
  • It will have to call the function if the value isn't known at compile time, like if it comes from some input. – Bo Persson Nov 13 '15 at 13:34
  • @BoPersson It seems not worked... – Daizy Nov 14 '15 at 02:37

2 Answers2

6

There's no separate math library on OSX. While a lot of systems ship functions in the standard C math.h header in a separate math library, OSX does not do that, it's part of the libSystem library, which is always linked in.

In addition to that, a compiler might optimize away any such call if it can perform the computation at compile time.

nos
  • 223,662
  • 58
  • 417
  • 506
0

sqrt is provided as a compiler built-in, so no link to the library is necessary (as it happens - doing so would still be good practice so that it compiles elsewhere).

Per this page:

The ISO C90 functions [long list including sqrt] are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin-function is specified for an individual function). All of these functions have corresponding versions prefixed with __builtin_.

If you compile with -fno-builtin I would expect a failure at the link stage.

abligh
  • 24,573
  • 4
  • 47
  • 84