Why the code only works when I use the %lf or %f place holder (second placeholder), but its printing 0 when I use %d?
#include <stdio.h>
void main()
{
long id;
id = 123456789;
double Hourly;
Hourly = 30;
int HoursAday, daysAweek, Fired, Hired;
HoursAday = 8; daysAweek = 5; Fired = 2021; Hired = 2019;
printf("bob, id: \"%d\" should get %lf", id, (Hourly * HoursAday * daysAweek) * (Fired - Hired));
CodePudding user response:
The type of (Hourly * HoursAday * daysAweek) * (Fired - Hired)
is double
so the correct specifier is %lf
. Because of variadic arguments default conversions the code will also work with %f
(*). But %d
is undefined behavior.
Also, the correct specifier for id
(which is of type long
) is %ld
. %d
is undefined behavior.
See the documentation for printf: https://en.cppreference.com/w/c/io/fprintf
(*) A float
variadic argument always gets converted to double
. So the printf
family of functions will never receive a float
, they will always receive a double
. That's why %f
and %lf
are for practical reasons equivalent.
CodePudding user response:
This expression
(Hourly * HoursAday * daysAweek) * (Fired - Hired)
has the type double
due to the usual arithmetic conversions because the variable Hourly
has the type double
. That is if one operand has the type double
and other operand has an integer type in a binary operation then the operand with the integer type is converted to the type double
.
Using the wrong conversion specifier %d
designed to output objects of the type int
with an object of the type double
invokes undefined behavior.
Pay attention to that in this conversion specifier %lf
the length modifier l
has no effect. So it is enough to use %f
.