On most systems, unsigned char will be promoted to signed int, which
should be printed using %d. You can usually -- probably on all existing
implementations -- get away with printing a signed int using %u, or an
unsigned int using %d, so long as the value is within the common range,
but it's not correct.

Harald van DÄ³k <> writes:
> On Sun, 02 Mar 2008 15:39:42 +0200, Ioannis Vranos wrote:
>> Harald van Dijk wrote:
>>> Any float argument to the variable arguments of a function will be
>>> promoted to double. Both are fine.
>>
>> I suppose the following are also correct:
>>
>> signed char sc= 15;
>> unsigned char uc= 130;
>>
>> printf("%d\t%hu\t%u", sc, uc, uc);
>
> On most systems, unsigned char will be promoted to signed int, which
> should be printed using %d. You can usually -- probably on all existing
> implementations -- get away with printing a signed int using %u, or an
> unsigned int using %d, so long as the value is within the common range,
> but it's not correct.

signed char definitely promotes to (signed) int, so the "%d" is ok.

The "%hu" should be "%hhu" ("%hu" is for unsigned short). The "%hhu"
format prints a value of type unsigned char; "the argument will have
been promoted according to the integer promotions, but its value shall
be converted to signed char or unsigned char before printing" (C99
7.19.6.1p7). That's exactly what "%hhu" is for.

Harald is correct about the "%u" format; "%hhu" is better than "%u",
even though "%u" is very likely to work as expected.

--
Keith Thompson (The_Other_Keith) <>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson wrote:
> Harald van DÄ³k <> writes:
>> On Sun, 02 Mar 2008 15:39:42 +0200, Ioannis Vranos wrote:
>>> Harald van Dijk wrote:
>>>> Any float argument to the variable arguments of a function will be
>>>> promoted to double. Both are fine.
>>> I suppose the following are also correct:
>>>
>>> signed char sc= 15;
>>> unsigned char uc= 130;
>>>
>>> printf("%d\t%hu\t%u", sc, uc, uc);
>> On most systems, unsigned char will be promoted to signed int, which
>> should be printed using %d. You can usually -- probably on all existing
>> implementations -- get away with printing a signed int using %u, or an
>> unsigned int using %d, so long as the value is within the common range,
>> but it's not correct.
>
> signed char definitely promotes to (signed) int, so the "%d" is ok.
>
> The "%hu" should be "%hhu" ("%hu" is for unsigned short). The "%hhu"
> format prints a value of type unsigned char; "the argument will have
> been promoted according to the integer promotions, but its value shall
> be converted to signed char or unsigned char before printing" (C99
> 7.19.6.1p7). That's exactly what "%hhu" is for.
>
> Harald is correct about the "%u" format; "%hhu" is better than "%u",
> even though "%u" is very likely to work as expected.

Thanks for the answer, I forgot to mention that I am talking about
C90/C95 here.

Ioannis Vranos wrote:
> Keith Thompson wrote:
>> Harald van DÄ³k <> writes:
>>> On Sun, 02 Mar 2008 15:39:42 +0200, Ioannis Vranos wrote:
>>>> Harald van Dijk wrote:
>>>>> Any float argument to the variable arguments of a function will be
>>>>> promoted to double. Both are fine.
>>>> I suppose the following are also correct:
>>>>
>>>> signed char sc= 15;
>>>> unsigned char uc= 130;
>>>>
>>>> printf("%d\t%hu\t%u", sc, uc, uc);
>>> On most systems, unsigned char will be promoted to signed int, which
>>> should be printed using %d. You can usually -- probably on all
>>> existing implementations -- get away with printing a signed int
>>> using %u, or an unsigned int using %d, so long as the value is
>>> within the common range, but it's not correct.
>>
>> signed char definitely promotes to (signed) int, so the "%d" is ok.
>>
>> The "%hu" should be "%hhu" ("%hu" is for unsigned short). The "%hhu"
>> format prints a value of type unsigned char; "the argument will have
>> been promoted according to the integer promotions, but its value
>> shall be converted to signed char or unsigned char before printing"
>> (C99
>> 7.19.6.1p7). That's exactly what "%hhu" is for.
>>
>> Harald is correct about the "%u" format; "%hhu" is better than "%u",
>> even though "%u" is very likely to work as expected.
>
>
> Thanks for the answer, I forgot to mention that I am talking about
> C90/C95 here.

Guest

On Mar 2, 3:30 pm, Ioannis Vranos <>
wrote:
> santosh wrote:
>
> >> Thanks for the answer, I forgot to mention that I am talking about
> >> C90/C95 here.
>
> > In which case you'll have to use %u.
>
> Thanks for the answer. So, if I want to print the numeric value of an
> unsigned char , can I use printf("%u") without a cast?

wrote:
> On Mar 2, 3:30 pm, Ioannis Vranos <>
> wrote:
>> santosh wrote:
>>
>>>> Thanks for the answer, I forgot to mention that I am talking about
>>>> C90/C95 here.
>>> In which case you'll have to use %u.
>> Thanks for the answer. So, if I want to print the numeric value of an
>> unsigned char , can I use printf("%u") without a cast?
>
> See http://groups.google.com/group/comp.std.c/browse_thread/thread/7af31515d3ae7f2b/f1cc2a95425424f0
> It's about a little different thing, passing int as a char, but
> I don't think it makes much difference here, because there is no
> definitive answer anyway. You can google more, there were much
> bigger threads about this stuff (including passing char instead
> of int, IIRC).

Guest

On Mar 2, 4:09 pm, Ioannis Vranos <>
wrote:
> wrote:
> > On Mar 2, 3:30 pm, Ioannis Vranos <>
> > wrote:
> >> santosh wrote:
>
> >>>> Thanks for the answer, I forgot to mention that I am talking about
> >>>> C90/C95 here.
> >>> In which case you'll have to use %u.
> >> Thanks for the answer. So, if I want to print the numeric value of an
> >> unsigned char , can I use printf("%u") without a cast?
>
> > Seehttp://groups.google.com/group/comp.std.c/browse_thread/thread/7af315...
> > It's about a little different thing, passing int as a char, but
> > I don't think it makes much difference here, because there is no
> > definitive answer anyway. You can google more, there were much
> > bigger threads about this stuff (including passing char instead
> > of int, IIRC).
>
> Does any of these threads reach a conclusion?

Are you kidding? A resolved DR would be a conclusion, otherwise
you read what people say and either agree or disagree. I personally
stick to the following: it's UB, but works fine here (where "here"
is "everywhere").

wrote:
>
> Are you kidding? A resolved DR would be a conclusion, otherwise
> you read what people say and either agree or disagree. I personally
> stick to the following: it's UB, but works fine here (where "here"
> is "everywhere").

Well, I think casting the value to the expected type by the printf(), is
the safest solution.

It's my opinion that the literal wording of the standard
differs from the stated intent for both C90/95 and C99.
The intent is that a common value to both should work as
an argument to either signed/unsigned version of an
integer rank.

However, the standard clearly ambiguates this, if not
actually precludes it, in many places. For instance,
va_arg() is required to work this way, but fprintf isn't
required to use va_arg().

The point is, if you want to be pedantic, then play it
safe.
> not with an interaction with an unsigned int constant
> or variable.

The reason I throw in a 0u is precisely to avoid
ambiguities around the promotion of unsigned char.
A cast would be sufficient, and more idiomatic, but
it's ugly IMHO.

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!