27

Possible Duplicate:
Why do you have to link the math library in C?

When I write a program that uses functions from the math.h library, why is it that I have to explicitly link to libm even though they are part of the C standard library?

For instance, when I want to use the sin() function I need to #include <math.h> but I also need to pass -lm to GCC. But for any other library from the standard library, I don't have to do that. Why the difference?

Community
  • 1
  • 1
lindelof
  • 34,556
  • 31
  • 99
  • 140

3 Answers3

31

In the old days, linkers were slow and separating the mostly unused math code from the rest made the compilation process go faster. The difference is not so great today, so you can add the -lm option to your default compiler configuration.


Note that the header <math.h> (or any other header) does not contain code. It contains information about the code, specifically how to call functions. The code itself is in a library. I mean, your program does not use the "<math.h> library", it uses the math library and uses the prototypes declared in the <math.h> header.

TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130
pmg
  • 106,608
  • 13
  • 126
  • 198
7

It's the same reason you have to explicitly link to libpthread on most implementations. When something new and scary is added to the standard library, it usually first gets implemented as a separate add-on library that overrides some of the symbols in the old standard library implementation with versions that conform to the new requirements, while also adding lots of new interfaces. I wouldn't be surprised if some historical implementations had separate versions of printf in libm for floating point printing, with a "light" version in the main libc lacking floating point. This kind of implementation is actually mentioned and encouraged for tiny systems in the ISO C rationale document, if I remember correctly.

Of course in the long-term, separating the standard library out like this leads to a lot more problems than benefits. The worst part is probably the increased load time and memory usage for dynamic-linked programs.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
2

Actually, the reason you normally don't need to link against libm for most math functions is that these are inlined by your compiler. Your program would fail to link on a platform where this is not the case.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
  • 1
    Most of `libm` is impossible to inline unless your inline function limit is several KB or you've enabled a hack like `-ffast-math` that allows the compiler to generate incorrect-but-fast code. – R.. GitHub STOP HELPING ICE Mar 24 '11 at 13:48
  • Well, on x86 sine and cosine are implemented inside the FPU and accessible with a single instruction, so inlining makes a lot of sense here. A program that only uses `sin()` will not need to link against `libm` on x86, thus hiding the missing library reference. – Simon Richter Mar 24 '11 at 15:21
  • Are you sure the FPU `sin` instruction can directly implement `sin()`? If I'm not mistaken it needs a nontrivial argument reduction step first. – R.. GitHub STOP HELPING ICE Mar 24 '11 at 17:01
  • 1
    Okay, that was a bad example, my apologies. `fabs()` is a better one on x86. My original point still stands: if all functions you use are inlined, then the program will link and work fine even if the math library is not linked, however that is not portable for obvious reasons. – Simon Richter Mar 24 '11 at 17:25
  • 1
    @SimonRichter The older ones among us remember the times where x86 processors did not have an embedded FPU. AFAIK, the first one with embedded FPU was the i486, and even that one had a crippled version without FPU (called i486SX). Plus, the OP did not ask for x86 explicitly. – Binarus Nov 14 '17 at 08:06