I was expecting to have 45.599998 and 0 or have the same values on both printf but i get different results: 45.599998 45.599983 Why?, What is happening?
Suppose we eliminate some of the undefined behavior in your code by using this variation:
#include <string.h>
#include <stdio.h>
int main() {
int v[4]={0,0,0,0};
float f = 45.6;
memcpy(&v[1], &f, sizeof f);
printf("%f\n", f);
printf("%f\n", v[1]);
return 0;
}
This still has undefined behavior because format directive %f
is not properly type-matched with v[1]
, but otherwise it is ok as long as float
is not larger than int
, and int
has no trap representations (both of which hold for most C implementations).
Even in the likely event that the values of f
and v[1]
have identical byte-sequence representations, the difference between their types has an important consequence with respect to this code. The variable arguments of a variadic function such as printf
are subject to the "default argument promotions". These leave values of type int
unchanged, but they promote float
s to type double
. Thus, if your float
and double
differ in practice, which they typically do, then
printf
receives different argument values in the two cases, even when only the byte sequence of each argument is considered, and
- in the
v[1]
case, printf
probably does not receive a wide enough value.
So if you want to indulge in the dubious practice of hypothesizing about what the program actually does in this case of undefined behavior, then one of the more likely possibilities is that in the v[1]
case it looks at the byte sequence of a float
, combined with some additional random bytes that happen to be laying around in memory, interprets them as if they were the bytes of a double
, and, by stroke of luck and the details of the chosen test value, it comes up with a numeric value close to, but not exactly matching the double
to which your float
was promoted.