3

I had a code that was working perfectly in windows but when i tried to compile it in linux i got an error. I found that the issue is with the sin() function.

If i pass to it a constant number directly, it works fine:

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

int main(void) {
    float y = sin(1.57);

    printf("sin(1.57) = %f", y);

    return 0;
}

Output 1:

sin(1.57) = 1.000000

But when i pass to it a variable i get an error:

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

int main(void) {

    float x = 1.5;
    float y = sin(x);

    printf("sin(%f) = %f", x, y);

    return 0;
}

Output 2:

/tmp/ccfFXUZS.o: In function `main':
source-bcfaa9ff162b:(.text+0x1a): undefined reference to `sin'
collect2: error: ld returned 1 exit status
rullof
  • 7,124
  • 6
  • 27
  • 36
  • Which compiler are you using? – Rahul Jan 21 '14 at 12:14
  • 5
    You probably aren't linking the math library and in your first example the compiler probably calculated the value for you (it's constant). Putting that variable in probably results in a call to `sin`. – ta.speot.is Jan 21 '14 at 12:15
  • 1
    ON GNU GCC version 4.8.1, it's running without error. – Rahul Jan 21 '14 at 12:16
  • Works fine with clang, too, without explicitly telling the linker to include the math library. – Wooble Jan 21 '14 at 12:18
  • `sin` expects a double. In your first snippet you pass a double, in your second one you pass a float. If you have a lot of warnings enabled or perhaps if you compile C as C++, that might be an issue. – Lundin Jan 21 '14 at 12:38
  • @Lundin But why it's generating this error? isn't `x` converted to double? – rullof Jan 21 '14 at 12:42
  • @rullof Yes it should get implicitly converted in C. More likely, the cause of the problem is that a math library wasn't linked to the program, as someone already answered. Still, is important to actually know what types you use in your own program, and how they get implicitly converted. – Lundin Jan 21 '14 at 12:48

2 Answers2

11

On some systems, the math functions are in a separate library, which needs to be linked explicitly. Simply pass the option -lm when compiling (linking) your program, and everything should work.

The reason the first one works is because the compiler knows about sin and optimized the whole thing to a constant - it doesn't need to actually call the sin function.

Michael Madsen
  • 54,231
  • 8
  • 72
  • 83
  • But why declaring `x` as double works without problem? – rullof Jan 21 '14 at 12:41
  • @rullof: The error has nothing to do with datatypes; it's the compiler telling you it can't find the code for the sin function (which it wants to use because it just sees a variable as the argument). – Michael Madsen Jan 21 '14 at 12:47
  • I undersood the error but why is this working https://eval.in/92815? – rullof Jan 21 '14 at 12:48
  • 1
    @rullof: Look carefully at the compiler selection: You're compiling the one with `double` as *C++* code. Your failing example is compiling as *C* code - and this is enough to change things. If you compile your double version as C code, it fails in the exact same way as the float version. – Michael Madsen Jan 21 '14 at 13:01
2

You need to link with -lm.

I don't know why the first example is working - maybe some optimizations ?

Zaffy
  • 16,801
  • 8
  • 50
  • 77