Reputation: 1369
Here is the code i was trying.I could not comprehend the output i got.Why is output some garbage value here and not 10?
#include<stdio.h>
#include<string.h>
void f(int);
void (*foo)(float)=f;
int main()
{
foo(10);
return 0;
}
void f(int i)
{
printf("%d\n",i);
}
Output is some garbage value.
Upvotes: 0
Views: 415
Reputation: 74365
Compiers usually emit warnings or errors in this case, e.g. GCC says:
program.c:4: warning: initialization from incompatible pointer type
Intel C Compiler is more verbose:
program.c(4): warning #144: a value of type "void (*)(int)" cannot be used to initialize an entity of type "void (*)(float)"
void (*foo)(float)=f;
^
Besides possible conversion of argument value 10
to floating point, there is another option if you are running on a 64-bit machine - calling convention. Integer arguments are passed through the regular integer CPU registers (RDI
, RSI
, etc.) while floating-point arguments are passed in the SSE registers (XMM0
, XMM1
, etc.). Even if somehow the floating point value was compatible with the integer one, the called function will receive its argument in different register (XMM0
) than the one it will consult for the value (RDI
).
On a 32-bit machine both integer and floating point arguments are passed on the stack. What you end up with is 1092616192
which is just 10.0
in IEEE 754 single-precision floating point representation:
1092616192 = 0|10000010|01000000000000000000000
| | |
| | +---> significand = 1 + 2^(-2) = 1.25
| |
| +------------> exponent = 130 - 127 = +3
|
+--------------> sign = 0 (positive)
1.25 * 2^3 = 1.25 * 8 = 10.0
Upvotes: 4
Reputation: 157324
This is undefined behaviour.
You're calling f
, which is a function taking an int
, as if it were a function taking a float
. The actual behaviour will depend on how the calling conventions of your platform work - for example, if int
and float
parameters are passed in the same register or the same stack slot the result will be that of aliasing the floating-point bit pattern representing 10.0f
as an int
. If on the other hand int
and float
are passed differently the result will be whatever garbage was in the appropriate register or stack slot.
Also, because this is undefined behaviour the compiler is at liberty to do whatever it likes, and if the optimiser is enabled it may well do.
Upvotes: 4
Reputation: 108968
Why is output some garbage
Because you lie to the compiler.
You tell it foo
is a pointer to a function that accepts a float
... but then point it to a function that accepts an int
.
Don't lie to the compiler
Upvotes: 4
Reputation:
Because of the different prototypes. The compiler treats "10" as a float, and uses its floating-point representation to call f()
, which in turn treats it as an ineteger, whose binary representation does not have the value "10".
Upvotes: 1
Reputation: 399743
Because of undefined behavior.
The call through foo()
converts the integer 10
to float
, which is then interpreted as an int
by f()
.
I'm pretty sure this isn't well-defined.
Upvotes: 2