Path: csiph.com!weretis.net!feeder9.news.weretis.net!news.quux.org!wilderland.ovh!ereborbbs.duckdns.org!eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Dodging undefined behaviour in printf
Date: Sun, 27 Sep 2026 10:48:36 -0700
Organization: A noiseless patient Spider
Lines: 43
Message-ID: <86v77qr3ez.fsf@linuxsc.com>
References: <119bf9d$1fk39$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Sun, 27 Sep 2026 17:48:39 +0000 (UTC)
Injection-Info: dont-email.me; logging-data="1683303"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/EUHo8EqPOt3Y7CGdud/SY6rgNxqyigD8="; posting-host="2656c84029572b3033be2dff7a8e2cf2"
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:a1/x5ms59IWCqsvXK0r5vNUqPD8= sha1:f0zptKRQblVG0d8ZendZ618bKhc= sha256:TZ3rmmaHTNrWbD54Q08wp7mInxj89uu6cMWBrtq/aik= sha1:9yNZx09pWqogzeo0NOvH3tvakW4= sha256:ZVEl33ZM0x6FUZ2OABkkyxqoyqREpFuH0zdB1BJgsGA=
Xref: csiph.com comp.lang.c:402429
highcrew writes:
> Dear c.l.c.
>
> I'm trying to refine my knowledge on the topic of type promotions, and
> now I know how promotion is implied when passing arguments to a
> function whose prototype is missing argument definition, or to
> functions having variadic argument list.
>
> So I was wondering about the following:
>
> unsigned short x = value;
> printf("%x", x);
>
> Assuming that sizeof(unsigned short) < sizeof(int), I would guess that
> x is promoted to signed int, which is however the wrong type, as it
> should be unsigned int.
Yes, usually unsigned shorts are promoted to signed ints, although
the rule is expressed in terms of value ranges rather than sizes.
> Well, it is is also true that the `int` value is not going to be
> negative for sure.
>
> Would this be a problem? Am I supposed to explicitly cast x to
> (unsigned int) when passing it to printf?
The short answer is that just using 'x' works. No cast is
needed. For variadic arguments, corresponding signed and
unsigned types are interchangeable, as long as the argument
value is within the range of both types. The same rule applies
for arguments subject to the default promotions, if the function
being called is defined without a prototype.
> I find it interesting that the problem is not a problem on
> architectures where sizeof(unsigned short) == sizeof(unsigned int) --
> if I will ever find such a thing.
>
> How about %hx then?
How %hx works is the same as how %x works, except that whatever
value is sent (obtained as an unsigned int) is first converted
to unsigned short before formatting.