Vindhya G
Vindhya G

Reputation: 1369

function pointers with different prototypes in c

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

Answers (5)

Hristo Iliev
Hristo Iliev

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

ecatmur
ecatmur

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

pmg
pmg

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

user529758
user529758

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

unwind
unwind

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

Related Questions