Search code examples
cfunctionfunction-prototypes

Why does this function print 0 when I pass in a nonzero value as its argument?


The code here:

#include <stdio.h>

int main(void) {
    test(7.4, 4);
    return 0;
}

void test(float height, float radius){
    printf("%f", height);    
}

Will print:

0.000000

Why is this? Why will it not just print 7.4?


Solution

  • In the program you wrote, you've called the test function without first prototyping it. Modern compilers will often reject this, but on older compilers - or compilers providing support for old C code - the program will implicitly try to deduce the argument types. You've provided 7.4 and 4 as arguments, meaning that the compiler expects that you're going to be passing in a double and an int, respectively, since 7.4 is a double literal, so it generates code to pass in the first argument as a double and the second as an int.

    Later, when you actually define test, you specify that the arguments are floats, which doesn't match the earlier code. As a result, that function tries to read its first argument as though it were a float, so it ends up reinterpreting some of the bytes in some way that happens to interpret them as a floating point number that's close to negative zero.

    To fix this, either prototype the test function before calling it, or define it before you use it. Note that my compiler with the warnings cranked up explicitly tells you about the implicit declaration and the definition mismatch:

    nodecl.c: In function ‘main’:
    nodecl.c:4:3: warning: implicit declaration of function ‘test’ [-Wimplicit-function-declaration]
       test(7.4, 4);
       ^
    nodecl.c: At top level:
    nodecl.c:8:6: warning: conflicting types for ‘test’
     void test(float height, float radius){
          ^
    nodecl.c:4:3: note: previous implicit declaration of ‘test’ was here
       test(7.4, 4);
       ^
    

    Going forward, if you see these warnings, you now know what they're talking about, and you should be able to diagnose your error more quickly.