1

Seeing it for the first time in life. When input parameters are changed the compiler gives error that the function is undefined. How can this happenenter image description here

In the image the first call to the function works without error. If I remove the sin function call with variable, this error is not there. Seriously curious.....

Ginu Jacob
  • 1,588
  • 2
  • 19
  • 35

2 Answers2

3

Here is why. Consider this code:

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

int main()
{
  printf("%.3f\n", sin(0.5));
  return 0;
}

GCC notices that you are taking the sine of a constant and replaces it with the actual value of sin(0.5) immediately, as you can see from the disassembly of main below:

(gdb) disass main
Dump of assembler code for function main:
   0x000000000040052d <+0>: push   %rbp
   0x000000000040052e <+1>: mov    %rsp,%rbp
   0x0000000000400531 <+4>: sub    $0x10,%rsp
   0x0000000000400535 <+8>: movabs $0x3fdeaee8744b05f0,%rax
   0x000000000040053f <+18>:    mov    %rax,-0x8(%rbp)
   0x0000000000400543 <+22>:    movsd  -0x8(%rbp),%xmm0
   0x0000000000400548 <+27>:    mov    $0x4005e4,%edi
   0x000000000040054d <+32>:    mov    $0x1,%eax
   0x0000000000400552 <+37>:    callq  0x400410 <printf@plt>
   0x0000000000400557 <+42>:    mov    $0x0,%eax
   0x000000000040055c <+47>:    leaveq 
   0x000000000040055d <+48>:    retq   
End of assembler dump.

Now let's change it so that the optimization is not possible:

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

int main(int argc, char** argv)
{
  printf("%.3f\n", sin((double)argc));
  return 0;
}

Now you actually need to call the sin() function which is defined in the math library. Linking will fail if you do not supply -lm flag in the right place of your options to gcc (best place is at the end). Here is the disassembly:

Dump of assembler code for function main:
   0x000000000040063d <+0>: push   %rbp
   0x000000000040063e <+1>: mov    %rsp,%rbp
   0x0000000000400641 <+4>: sub    $0x20,%rsp
   0x0000000000400645 <+8>: mov    %edi,-0x4(%rbp)
   0x0000000000400648 <+11>:    mov    %rsi,-0x10(%rbp)
   0x000000000040064c <+15>:    cvtsi2sdl -0x4(%rbp),%xmm0
   0x0000000000400651 <+20>:    callq  0x400540 <sin@plt>
   0x0000000000400656 <+25>:    movsd  %xmm0,-0x18(%rbp)
   0x000000000040065b <+30>:    mov    -0x18(%rbp),%rax
   0x000000000040065f <+34>:    mov    %rax,-0x18(%rbp)
   0x0000000000400663 <+38>:    movsd  -0x18(%rbp),%xmm0
   0x0000000000400668 <+43>:    mov    $0x400704,%edi
   0x000000000040066d <+48>:    mov    $0x1,%eax
   0x0000000000400672 <+53>:    callq  0x400510 <printf@plt>
   0x0000000000400677 <+58>:    mov    $0x0,%eax
   0x000000000040067c <+63>:    leaveq 
   0x000000000040067d <+64>:    retq   
End of assembler dump.

Note the call to sin@plt.

From your screenshot it looks like you are using some kind of a visual tool around gcc. Check the documentation on it how to change the linker libraries. If it will let you directly modify the linker command, just place -lm at the end of it and your code should work.

Sasha Pachev
  • 5,162
  • 3
  • 20
  • 20
0

This is just conjecture. If you use a math library and you only add a header on top, the error is because you didn't link with the library. maths.h should be work for you.

Scott Deng
  • 119
  • 8