Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to `pow' when the exponent is changed?

Tags:

c

I'm having some strange issues with pow(). If i do

return 44330*(1 - pow((float) pressure / PRESSURE0, 1/5.255F));

where pressure is an int32_t and PRESSURE0is a constant, I get an error saying undefined reference to `pow'. However, if I do

return 44330*(1 - pow((float) pressure / PRESSURE0, 1.0F));

it's fine. Am I doing something wrong?

Thanks

like image 701
Kar Avatar asked May 20 '15 05:05

Kar


People also ask

What is undefined reference to POW?

The undefined reference to pow error is invoked if we miss the <math. h> header file or the program is not compiled correctly. To avoid this error, make sure you have included the header file and it is recommended to compile the program using the GCC with -lm argument.

Why POW function is not working in C?

Working of pow() Function in C But the function does not always work with integers. For example, if the value returned by pow(4, 3) is assigned to an integer variable, the output might be 63 on some compilers and 64 on other compilers.

Why POW is not working in Ubuntu?

The error is because you are trying to use the (integer) modulo operator % with the return value of pow (which has type double ).

How do you fix undefined reference error in C?

The error: undefined reference to function show() has appeared on the terminal shell as predicted. To solve this error, simply open the file and make the name of a function the same in its function definition and function call. So, we used to show(), i.e., small case names to go further.


1 Answers

Generally, in order to use math functions like sqrt(), pow() etc. you need to link with the math library, libm (on gcc, use the -lm option).

However, the compiler is free to apply optimizations, especially when the arguments to the functions are constants. Consider the following two simplified functions:

double f1(int pressure) {
   return pow((float) pressure / PRESSURE0, 1/5.255F);
}

double f2(int pressure) {
   return pow((float) pressure / PRESSURE0, 1.0F);
}

This gets compiled into i386 code as follows (unnecessary assembler directives removed):

f1:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp

; (float) pressure / PRESSURE0
        fildl   8(%ebp)
        fldl    .LC0
        fdivrp  %st, %st(1)

; pow()
        fldl    .LC1
        fstpl   8(%esp)
        fstpl   (%esp)
        call    pow

        leave
        ret
f2:
        pushl   %ebp
        movl    %esp, %ebp

; (float) pressure / PRESSURE0
        fildl   8(%ebp)
        fldl    .LC0
        fdivrp  %st, %st(1)

; NO call to pow(x, 1.0), since it would not change the value of x

        popl    %ebp
        ret

In f2(), since the exponent to pow() is 1.0, there is no need to call the pow() function - the compiler detects this and removes the function call. Hence, if there are no other calls to any math functions in your code, it is not necessary to link against libm in that particular case.

See also

  • literal constant vs variable in math library
  • Do math functions of constant expressions get pre-calculated at compile time?
like image 136
Andreas Fester Avatar answered Oct 05 '22 23:10

Andreas Fester