3

I was trying to compile a source file that includes <math.h>. However I succeeded in creating an executable, no error without linking to libm.a.

The command I typed was gcc -Wall filename.c -o executablename

I was told to link to the external libraries (i.e/ libraries other than libc.a)

What's going on?

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

int main(void)
{
    double x = sqrt(2.0);
    printf ("The sqrt of 2 is: %f\n", x);
    return 0;
}
Daniel Jee
  • 664
  • 5
  • 10

3 Answers3

6

The math functions you call are implemented by compiler built-in functions. Try the following if you want to see an error message:

gcc -fno-builtin -Wall filename.c -o executablename

For example, on my platform (Ubuntu 14.04.3 LTS), I get this error message:

$ cat x.c
#include <math.h>
#include <stdio.h>

int main(void)
{
    double x = sqrt(2.0);
    printf ("The sqrt of 2 is: %f\n", x);
    return 0;
}
$ gcc -fno-builtin x.c
/tmp/ccpjG2Pb.o: In function `main':
x.c:(.text+0x1c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Nope even with the -fno-builtin and -Wall flags it still compiles without an error – Daniel Jee Jul 27 '16 at 05:58
  • Please reduce your program to the shortest possible program that still demonstrates your question. Please copy-paste that program into your question. See [mcve] for more info. – Robᵩ Jul 27 '16 at 05:59
  • I was able to reproduce the above error with the option `-fno-builtin`. Without it, the program compiles even if I haven't specified the `-lm` option to gcc. – jdhao Dec 10 '20 at 13:12
  • @jdhao - That is precisely the same behavior I describe in my answer. – Robᵩ Dec 10 '20 at 19:47
0

Some compilers, like the current clang on OS X (which masquerades as gcc) do not need to be told to link your executable with the math library.

The clang on OS X will link your executable with /usr/lib/libSystem.B.dylib (and only this for a simple program). This library in turn uses the library /usr/lib/system/libsystem_m.dylib which is the math library.

Kusalananda
  • 14,885
  • 3
  • 41
  • 52
  • What if I'm using gcc on cygwin – Daniel Jee Jul 27 '16 at 06:11
  • @hemel Check what libraries are linked against your compiled executable. On an ordinary Unix system, this would be done with `ldd a.out`. You might spot `libm` in there. It's never _wrong_ to link with `-lm` when you use math functions... and since this has to do with linking rather than compiling, I don't think `-Wall` would do very much in terms of reporting (since it mainly deals with code issues, not linking issues). – Kusalananda Jul 27 '16 at 06:34
0

The functions in <math.h> (or the preferable <tgmath.h>) are part of the C library just as many other functions. It is platform dependent if all the functions in the C library are actually linked in one single library or separately in multiple chunks.

In ancient times the size of the libraries was a problem for link time, the larger a library was, the longer it took to link executables that had many unresolved symbols. These times are long gone, but the separation on some platforms into libc.a and libm.a prevails.

If your platform doesn't need -lm for linking it should have a dummy (empty) version of libm.a just that there is no error when you have that on your link command line. This is for example the case for the musl C library that is at the base of Alpine Linux.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Another historical reason for the separate maths library was that some machines didn't have hardware floating point and so needed a software emulation library, while others did have hardware floating point and didn't need the emulation. This was easier to manage if the two libraries were separate. – Jonathan Leffler Jul 27 '16 at 06:58
  • Does that mean that libc.a may support functions of libm.a? – Daniel Jee Jul 27 '16 at 07:05
  • @hemel The `libc` (or whatever the system chooses to call it) can contain everything, including math, cryptographic, networking and graphics rendering routines if it makes sense on a particular platform. – Kusalananda Jul 27 '16 at 07:22
  • @hemel, I suppose you mean if it can contain functions from ``? Yes. How the linking is done is not part of the C standard. – Jens Gustedt Jul 27 '16 at 07:24