Reputation: 68
I have encounter a problem which can be summarized as follows,
#include <stdio.h>
int main()
{
float f=23.45;
printf("main: %f\n", f);
t1(f);
/* the result would be
main:23.450001
t1:2.000000 */
}
void t1(float f)
{
printf("t1: %f\n", f);
}
I know now that the weird behavior is due to missing of prototype declaration and the arguments are thus promoted,(float->double?),still i cannot figure out why the result is 2.000000,so can anyone give a more detailed explanation? I am using ubuntu10.04 gcc4.4.3
Upvotes: 0
Views: 136
Reputation: 80276
The behavior you are observing is specific to stack-based parameter passing. For people who compile 64-bit x86 code by default and are unable to reproduce it, you can try with "gcc -m32" instead of just "gcc".
With stack-based parameter passing, t1()
read 32 bits from the stack, and these 32 bits happen to form the floating-point value 2.0
.
At the call site, because t1
did not have a prototype, the argument f
was promoted to double
and it was a double
that was written on the stack (C99 6.5.2.2:6 “If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions”).
There is no reason for t1
to recover the intended value from the stack since it does not read it properly with the same type and width it was written.
Upvotes: 6
Reputation: 182763
Because the compiler does not know that t1
takes a float, it promotes the float to a double. On your platform, t1
interprets the first four bytes of that double as a float.
2.0 is represented as 1 x 2^0, which in binary is three zero bytes followed by a 64 (on x86-64). As it happens, 23.45 as a double has the same first four bytes, 0, 0, 0, 64 (followed by 51, 115, 55, 64). So if you take the double 23.45 and interpret the first four bytes of it as a float, you get 2.0.
Upvotes: 1
Reputation: 36049
Remember that a missing prototype implies the function will later be declared with int arguments, and that appropriate conversions take place. So, I assume if you replace the float by int in the declaration of t1, you'll get a result of 23.
Upvotes: 0