In an interview, I was asked what do I think about the following code:
#include <stdio.h>
int main()
{
float f = 10.7;
int a;
a = f;
printf ("%d\n", a);
}
I answered:
The compiler will emit a warning as you are changing a float
to an int
without a cast.
The int
will have garbage value as you are not using a cast.
Then, they allowed me to run the program on a online compiler. I was overwhelmed. Both my assumptions were wrong. The compiler did not emit any warnings, and the int
had the value 10. Even when I changed, the float
to a value like 10.9, or 10.3, the answer was the same. Even putting a cast
did not change the result.
Can someone tell me why this happens and in what cases will the result be different.
NOTE: While compiling, the interviewer told me to add no gcc
flags.
EDIT: Now I have understood, that the float does not get rounded off, and the answer will be 10. But can someone explain me why is this designed like this? Why does any float when converted to an int, be rounded below? Is there a specific reason?
This is what the standard 6.3.1.4 says:
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
The undefined behavior part is regarding size and signedness of the integer. If you picked an integer which is too small to contain the result, it invokes undefined behavior.
The int will have garbage value as you are not using a cast
The int may have a garbage value in case of overflow, but the presence or lack of cast has nothing to do with it.
A compiler is never required to show a "warning", warnings are not something specified by the C standard, which only speaks of diagnostics (that is, some kind of message, call it error or warning). Therefore you can never portably assume that every compiler will give a warning of any kind.
In this case of implicit float-to-int conversion, the compiler is not required to display any form of diagnostic at all. Good compilers will, however.
In the case of GCC, it is rather sloppy about such warnings, you have to tell it explicitly to give the warnings by adding -Wconversion
or -Wfloat-conversion
. These are the extra flags hinted at.