'#' conversion flag in printf() doesn't work with NULL character

E

Erik Leunissen

L.S.

I've observed unexpected behaviour regarding the usage of the '#' flag
in the conversion specification in the printf() family of functions. Did
I detect a bug, or is there something wrong with my expectations
regarding the effect of the following code:

printf("NULL as hex: %#4.2x\n", '\0');


Expected output
===============

NULL as hex: 0x00



Observed output (white space is significant)
===============

NULL as hex: 00



Thanks in advance for any comments,

Erik Leunissen
==============
 
W

Walter Roberson

:I've observed unexpected behaviour regarding the usage of the '#' flag
:in the conversion specification in the printf() family of functions.

: printf("NULL as hex: %#4.2x\n", '\0');

:Expected output
:NULL as hex: 0x00
:Observed output (white space is significant)
:NULL as hex: 00

The C89 standard says that # indicates that an alternate output form
should be used, and that for hex, non-zero values will have 0x or 0X
prepended. You happen to be outputing the zero value, so you have
fallen into behaviour that the standard does not nail down. The
C89 standard doesn't say that 0x cannot be prepending for the zero value,
but it doesn't require it either.
 
E

Erik Leunissen

Thanks for providing clarity.

Apart from that clarity, does anybody know the reason why the C89
standard makes an exception in (deliberately?) not specifying the
behaviour for the NULL character?


TIA,

Erik Leunissen
 
W

Walter Roberson

:Apart from that clarity, does anybody know the reason why the C89
:standard makes an exception in (deliberately?) not specifying the
:behaviour for the NULL character?

To be pedantic, it doesn't make any exception for the NULL character.
You are using a hex formatter, not a character formatter, so if you
happen to passed a char as the value, it is going to undergo
The Usual Integral Promotions. There's nothing special about the
NULL character: it's just another value which happens to be 0.

I have no ideas why the alternative representation for 0
has no 0x for the hex formatter. Possibly because it isn't needed.
0 remains the same in any base, but leading 0's before a value
can indicate octal to strtol.
 
B

Ben Pfaff

:Apart from that clarity, does anybody know the reason why the C89
:standard makes an exception in (deliberately?) not specifying the
:behaviour for the NULL character?

To be pedantic, it doesn't make any exception for the NULL character.

To be pedantic, there is no NULL character. NULL is a null
pointer constant. NUL is an ASCII code point.
 
V

Villy Kruse

:I've observed unexpected behaviour regarding the usage of the '#' flag
:in the conversion specification in the printf() family of functions.

: printf("NULL as hex: %#4.2x\n", '\0');

:Expected output
:NULL as hex: 0x00
:Observed output (white space is significant)
:NULL as hex: 00

The C89 standard says that # indicates that an alternate output form
should be used, and that for hex, non-zero values will have 0x or 0X
prepended. You happen to be outputing the zero value, so you have
fallen into behaviour that the standard does not nail down. The
C89 standard doesn't say that 0x cannot be prepending for the zero value,
but it doesn't require it either.

So I usualy use the format 0x%02x if I want that result. Anyway, for the
value 0 or '\0' there are no ambiguity in enterpreting the printed data.

Villy
 
M

Michael Mair

Villy said:
So I usualy use the format 0x%02x if I want that result. Anyway, for the
value 0 or '\0' there are no ambiguity in enterpreting the printed data.

Well, base 1 numbers certainly are unpopular, even though
they would greatly simplify the arithmetic stuff ;-)


Cheers
Michael
 
L

Lawrence Kirby

Thanks for providing clarity.

Apart from that clarity, does anybody know the reason why the C89
standard makes an exception in (deliberately?) not specifying the
behaviour for the NULL character?

If you mean converting a zero value then there's a simple reason. A zero
value is unambiguous in any base (integer base >= 2 anyway). The output
format generated by # might be useful for some purposes and can't be
otherwise generated in a simple printf() call. OTOH if you want 0x or 0X
to be output in all cases that can be done trivially by putting 0x or 0X
explicitly in the format string. So there's little point in making a
special modifier to do that.

Lawrence
 
L

Lawrence Kirby

On Wed, 23 Feb 2005 19:59:33 +0000, Walter Roberson wrote:

....
The C89 standard says that # indicates that an alternate output form
should be used, and that for hex, non-zero values will have 0x or 0X
prepended. You happen to be outputing the zero value, so you have
fallen into behaviour that the standard does not nail down. The
C89 standard doesn't say that 0x cannot be prepending for the zero value,
but it doesn't require it either.

This is incorrect. The standard defined # as a "modifier" and says where
the # form differs from the non-# form. Where the standard does not say
that it differs then it must be the same. I.e. for a valid zero valued
argument %#4.2x is required to produce the same output as %4.2x because
nothing in the standard allows it to be different.

Lawrence
 
W

Walter Roberson

:> The C89 standard says that # indicates that an alternate output form
:> should be used, and that for hex, non-zero values will have 0x or 0X
:> prepended. You happen to be outputing the zero value, so you have
:> fallen into behaviour that the standard does not nail down. The
:> C89 standard doesn't say that 0x cannot be prepending for the zero value,
:> but it doesn't require it either.

:This is incorrect. The standard defined # as a "modifier" and says where
:the # form differs from the non-# form. Where the standard does not say
:that it differs then it must be the same. I.e. for a valid zero valued
:argument %#4.2x is required to produce the same output as %4.2x because
:nothing in the standard allows it to be different.

The C89 standard defines the result of converting non-zero numbers
with # as the flag (not "modifier" by the way) and x or X as the
conversion, and defines several other alternate conversions. The standard
also says that the result for all other conversions is undefined.
As the standard does not say what happens when converting 0 with %#x
then it falls under the category of "other conversions" and hence
has an undefined result.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top