9

Let's say I have the following code snippet:

int i; double value;
for(i = 0; i < CONSTANT; i++) {
  value = (double)pow(2, i);
}

Trying to compile this code yields an "undefined reference to `pow'" error.

Including or excluding math.h makes no difference, since it ends up being included anyway.

Raising 2.0 to a hardcoded power works okay, but everything fails if I substitute the exponent by an expression that contains i.

What am I doing wrong? Thanks.

  • What compiler are you using? Is there any other possible declaration of `pow()`? Could you quote the error exactly? – David Thornley Dec 13 '10 at 16:41
  • I'm using GCC and there is no other declaration of `pow`. The question is definitely answered; almost all of the answers helped me out. I wish I could accept more than one. :) Thanks, everyone. –  Dec 13 '10 at 16:52
  • 5
    While others have commented on why `pow` wasn't working, the whole fact that you're using `pow` is a huge problem with your code. **C has an operator for exponents base 2** and it's called `<<`. Remove this useless use of `pow` and replace it with `1< – R.. GitHub STOP HELPING ICE Dec 13 '10 at 17:02
  • That would only work for `CONSTANT <= 32`, or possibly 64 with `long [long]`. – zwol Dec 13 '10 at 20:06
  • `pow` returns `double`, so the cast `(double)` is useless – phuclv May 23 '17 at 14:25

5 Answers5

16

It's a very interesting behavior, and a good learning example.

To solve your problem, add

-lm

to your gcc command line (provided you're using gcc). This tells the compiler to link against the math library.

What seems to be going on, is that if you're using

pow(2.0, 3);

the compiler realizes this expression evaluates to a constant, and does mere substitution.

Thus, no library function has to be called.

qdot
  • 6,195
  • 5
  • 44
  • 95
  • This is the explanation I was about to post. The compiler may also be able to optimize `pow(n, 2)` to `n*n`, or similar. – zwol Dec 13 '10 at 16:40
  • 1
    Actually, as a follow-up comment.. compiling that loop alone, with maximum optimization (-O3) actually works without -lm. This is because the value is not used further, and the compiler simply unrolls and optimizes the useless loop and useless pow() away, thus never needing to call the pow() function from the libm library. – qdot Dec 13 '10 at 16:42
  • Compiler would have to determine what function will be linked to make such optimalization, how does it do that? – jbulatek Mar 07 '23 at 10:20
3

You need to link with -lm to actually include the math library.

It worked for a hardcoded value because the compiler optimized the pow call away.

Tyler Eaves
  • 12,879
  • 1
  • 32
  • 39
3

You must link against the math library:

gcc program.c -lm

The reason is that GCC (and some other compilers) have a built-in pow() function for literal constants. So if you call pow() with 2.0 manually, the compiler will actually figure-out what the answer is and substitute that for you. With a variable input, the compiler must rely on the math library, which you must link against.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
1

The code for pow is part of the math library. You need to link in that library (in addition to the C library that is linked in by default).

To do that, with gcc, specify -lm on the compiler invocation

gcc ... -lm
pmg
  • 106,608
  • 13
  • 126
  • 198
  • 3
    Minor caveat: `-l` switches must always be placed *after* all object files on the command line. It happens to work on some Linux distributions if you don't, but it is not to be relied on. – zwol Dec 13 '10 at 16:46
0

http://www.cplusplus.com/reference/clibrary/cmath/pow/

In C, only the version taking two double parameters exists with this name. The other overloads are only available in C++.

It looks like you can't pass an int, so just make i a double and that should work.

Antony Woods
  • 4,415
  • 3
  • 26
  • 47