Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error In using math function in gcc?

When I am passing constant value in log2() as follow

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

int main(int argc, char* argv[]) 
{
int var;
var= log2(16);
printf("%d",var);
return 0;
}

gcc prog.c (NO Error) 4

But when I am passing variable in function log2(var) gives error undefined reference to `log2' I require to link library i.e. -lm

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

int main(int argc, char* argv[]) 
{ 
int var,i;
i= log2(var);
printf("%d",i);
return 0;
}

Gives error

undefined reference to `log2'
like image 568
krishna Avatar asked Apr 01 '13 05:04

krishna


1 Answers

In the first piece of code, the compiler replaces log2(16) with the constant 4. The compiler usually optimizes constant math this way. That's the reason you don't see an error.

See the generated code for confirmation. This is for your first version:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    $4, 28(%esp)
    movl    $.LC0, %eax
    movl    28(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    movl    $0, %eax
    leave
    ret

There is no call to log2. The compiler already replaced it by the constant 4 (movl $4, 28(%esp)).

This one is for your second version:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $48, %esp
    fildl   40(%esp)
    fstpl   (%esp)
    call    log2
    fnstcw  30(%esp)
    movzwl  30(%esp), %eax
    movb    $12, %ah
    movw    %ax, 28(%esp)
    fldcw   28(%esp)
    fistpl  44(%esp)
    fldcw   30(%esp)
    movl    $.LC0, %eax
    movl    44(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    movl    $0, %eax
    leave
    ret

As you can see there is a call log2 in this version. Thats why -lm is needed for the second version.

like image 195
jman Avatar answered Oct 20 '22 14:10

jman