You're calling the get_val()
function with no visible declaration.
Don't do that. As of C99, the language forbids (see below) any call to a function without a visible declaration. (That declaration should be a prototype, which specifies the types of the parameters, but that's not required.)
Prior to C99 (which dropped the "implicit int
" rule), a call to an undeclared function would require the compiler to assume that the function returns a result of type int
, and that it expects the number and types of arguments that the call actually passes. If that assumption is violated by the actual function definition, as it is here since get_val()
returns a double
result, the behavior is undefined.
(By "forbids", I mean that such a call is a constraint violation. That means a conforming compiler must diagnose it, but is not required to reject it. Many compilers still permit calls to undeclared functions, often with a non-fatal warning, and implement the pre-C99 semantics. So a compiler might let you get away with it. Don't.)
So what happens is that get_val()
is called, it returns a double
result with the value 5.6
-- but the caller is expecting an int
result, so it stores some undefined garbage value in a
.
The value you're seeing, 1717986918
, happens to be 0x66666666
in hexadecimal. In IEEE floating-point, at least on my system, the value 5.6
is represented as 0x6666666666661640
. Apparently the value being stored happens to be the first half of the double
value (most likely double
is 8 bytes and int
is 4 bytes).
So that explains the behavior you're seeing, but you should not count on it.
Never call a function without a visible declaration.
The usual way to get a visible declaration for a function defined in another source file is to #include
the right header.
Here's an example of the right way to do it:
f1.h
:
#ifndef F1_H
#define F1_H
extern double get_val(void);
#endif
f1.c
:
#include "f1.h"
double get_val(void)
{
return 5.6;
}
f2.c
:
#include <stdio.h>
#include "f1.h"
int main(void) {
int a = get_val();
printf("%d\n", a);
return 0;
}
Note that I've changed ()
to (void)
in all the function declarations and definitions. This specifies that the function takes no arguments, rather than an unspecified number of arguments. The difference is that with double get_val()
, the compiler (probably) won't complain if you call it incorrectly, for example get_val("foo")
.