if printf converts promoted arguments to the types as specified by the
conversion specifiers,
This conversion only occurs when the promoted type corresponding to the
type indicated by the conversion specifier is different from type
indicated by the specifier.
the conversions are done as per the Converson section 6.3
when will 7.19.6.1.p9 come into use?
There are four types that are relevant here. Let type_a be the type of
the argument to fprintf(), and let type_ap be the corresponding promoted
type. Let type_s be the type indicated by the conversion specifier, and
let type_sp be the corresponding promoted type.
fprintf() attempts to extract a parameter value of type type_sp from
it's argument list (by a mechanism similar to va_arg(), though it need
not actually use va_arg()). The value is then converted to type_s, if
necessary (it can only be necessary if type_sp is different from type_s).
7.19.6.1p9 applies whenever type_ap is different from type_sp. The
problem is NOT the conversion to type_s, it's the extraction from the
argument list of a value of type type_sp, If type_ap is incompatible
with type_sp, that extraction has undefined behavior (7.15.11p2).
However, 7.19.6.1p9 is worded a little more strongly than that. It
doesn't just require that type_sp be compatible with type_ap; it says
that the behavior is undefined unless type_s is the same as type_a. This
is not something that can be easily explained in terms of the fprintf()
being written as an ordinary C function using the <stdarg.h> mechanisms
to extract it's arguments, since those mechanisms are not sensitive in
any way to the argument's type before promotion. Possibly, this is a
defect in the standard.
However, it's possible to imagine an implementation of fprintf() that
could be sensitive to cases where type_a was not the same as type_s,
even though type_ap is compatible with type_sp. We have to assume, first
of all, that the argument passing mechanism contains or at least depends
upon the type_a, and not just upon type_ap. The <stdarg.h> mechanisms
provide no mechanisms that depend upon the original type, rather than
the promoted type. However, as a non-standard extension, a fully
conforming implementation of C could add features to <stdarg.h> that do
depend upon the type before promotion. Those features could not
interfere with any user code that restricts itself to using the
standard-defined features. However, fprintf() could use these
extensions, and thereby become sensitive to any difference between
type_a and type_s.
I can't think of any good reason for doing this, other than sheer
perversity, but as currently worded, 7.19.6.1p9 allows such an
implementation.