result of
printf("%d\n", 5.0 + 2);
is 0
but
int num = 5.0 + 2;
printf("%d\n", num);
is 7
What's the difference between the two?
The result of 5.0 + 2 is 7.0 and is of type double.
The "%d" format is to print int.
Mismatching format specification and argument type leads to undefined behavior.
To print a float or double value with printf you should use the format "%f".
With
int num = 5.0 + 2;
you convert the result of 5.0 + 2 into the int value 7. Then you print the int value using the correct format specifier.
 
    
    In all expressions, every operand has a type. 5.0 has type double. 2 has type int.
Whenever a double and an integer are used as operands of the same operator, the integer is silently converted to a double before calculation. The result is of type double.
And so you pass double to printf, but you have told it to expect an int, since you used %d. The result is a bug, the outcome is not defined.
But in case of int num = 5.0 + 2;, you first get a result as double, 7.0. Then force a conversion back to int. That code is equivalent to:
int num = (int)((double)5.0 + (double)2);
More details here: Implicit type promotion rules
 
    
    The result of expression 5.0 + 2 is of type double, since at least one of the two operands of operator + here is a floating point / double value (so the other one will be converted to double before adding).
If you write printf("%d\n", 5.0 + 2), you will pass a floating point value where the format specifier actually expects an int. This mismatch is undefined behaviour, and the 0 you receive could be something else (another number, a crash, a .... what ever), too.
int num = 5.0 + 2, in contrast, will convert the double-value resulting from 5.0 + 2 back to an integral value (discarding any fractional part). So the value of num will be 7 and will be - since num is an integral type - valid in conjunction with format specifier %d then.
 
    
    5.0+2 is typed double.
The compiler warning for
int main() { return _Generic(5.0 + 2, struct foo: 0); }
should tell you as much if
int main() { return _Generic(5.0 + 2, double: 5.0+2); }
compiling without error doesn't.
Matching "%d" with a double in printf results in undefined behavior.
Any result is legal, including your harddrive getting erased (unlikely to happen unless your program already has such functionality somewhere in it; if it does, UB can well result it it being inadvertently invoked).
 
    
    The usual arithmetic conversions are implicitly performed to cast their values to a common type. The compiler first performs integer promotion; if the operands still have different types, then they are converted to the type that appears highest in the following hierarchy -
In int num = 5.0 + 2; this code snippet you are adding a float with integer and storing back to integer again. So, c automatically casts the result into integer to store in an integer type variable. So, while printing using %d, it prints fine.
But, in printf("%d\n", 5.0 + 2); this code snippet, the addition is casted into floating point number as float has higher priority over integer, but you are printing it using %d. Here mismatch of format specifier causing the unexpected result.
