Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

printf formats for size_t?

493 views
Skip to first unread message

David Mathog

unread,
May 12, 2005, 1:44:40 PM5/12/05
to
size_t varies from system to system. This occasionally leads to
coding issues such as:

(void) sprintf(msg,"length of buffer: %d",strlen(msg));

which worked fine on a 32 linux but triggered errors with gcc
on an X86_64 system. (Ok, it should probably have been a %u rather
than a %d, but since msg was always going to be short it didn't
affect the program's execution.)

The gcc printf man page indicates that "%zu", "%zx", etc. tell the
compiler that the variable has type size_t, whatever size_t happens to
be. Is "z" part of the C standard or is it a gcc extension? If the
former, at what point did "z" become part of C?


Thanks,

David Mathog
mat...@caltech.edu

Jens.T...@physik.fu-berlin.de

unread,
May 12, 2005, 2:08:26 PM5/12/05
to
David Mathog <mat...@caltech.edu> wrote:
> size_t varies from system to system. This occasionally leads to
> coding issues such as:

> (void) sprintf(msg,"length of buffer: %d",strlen(msg));

> which worked fine on a 32 linux but triggered errors with gcc
> on an X86_64 system. (Ok, it should probably have been a %u rather
> than a %d, but since msg was always going to be short it didn't
> affect the program's execution.)

Even better cast the size_t value to unsigned long and print with
"%lu", so it works also if size_t is larger than int.

> The gcc printf man page indicates that "%zu", "%zx", etc. tell the
> compiler that the variable has type size_t, whatever size_t happens to
> be. Is "z" part of the C standard or is it a gcc extension? If the
> former, at what point did "z" become part of C?

With the C99 standard. It says:

'z' Specifies that a following 'd', 'i', 'o', 'u', 'x', or
'X' conversion specifier applies to a 'size_t' or the
corresponding signed integer type argument; or that a
following 'n' conversion specifier applies to a pointer
to a signed integer type corresponding to 'size'_t argu-
ment.
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.T...@physik.fu-berlin.de
\__________________________ http://www.toerring.de

Keith Thompson

unread,
May 12, 2005, 5:28:00 PM5/12/05
to

As Jens Toerring pointed out, the "%zu" format is new in C99. That
means that some systems don't yet support it. (Incidentally, there is
no "gcc printf man page". printf is part of the runtime library; gcc
is just the compiler. gcc typically uses the native runtime library
on a given system, so having a current version of gcc is no guarantee
that printf() supports "%zu".)

For C90, the best way to print a size_t value is to use "%lu" and cast
the value to unsigned long. This will *almost* always work in C99 as
well. The only case where it won't is when size_t is bigger than
unsigned long (I don't know of any platforms where this is the case)
*and* the specific value you're printing exceeds ULONG_MAX.

For complete portability, you can query the __STDC_VERSION__ macro
(first check whether it's defined, then check the value) to determine
whether the implementation supports C99. On the other hand, just
because the compiler defines __STDC_VERSION__ as 199901L, that doesn't
necessarily guarantee that runtime library is also conforming. It
should, and it's arguably a bug if it doesn't, but it's a bug I've
seen on at least one real system.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

CBFalconer

unread,
May 12, 2005, 6:25:26 PM5/12/05
to

However this is actually implemented in the library, which supplies
a large interpreter for the printf formatting system [1]. This
means that you can have a compiler (such as gcc executed with
-std=C99) that accepts the code, and have things fail at run time.
The libraries are usually supplied with the operating system. Be
warned.

[1] This large interpreter is the reason to avoid printf and
friends when compact code is required. Specialized routines
outputting via putc or fputs can save a good deal of code space,
especially in embedded systems.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html


tedu

unread,
May 12, 2005, 6:41:42 PM5/12/05
to
Keith Thompson wrote:

> For C90, the best way to print a size_t value is to use "%lu" and
cast
> the value to unsigned long. This will *almost* always work in C99 as
> well. The only case where it won't is when size_t is bigger than
> unsigned long (I don't know of any platforms where this is the case)
> *and* the specific value you're printing exceeds ULONG_MAX.

64 bit Windows. long is still 32 bits. see
http://www.microsoft.com/whdc/driver/kernel/64bit_chklist.mspx for more
fun.

Keith Thompson

unread,
May 12, 2005, 6:57:47 PM5/12/05
to

Putting the "backwards" in "backwards compatibility".

Clark S. Cox III

unread,
May 13, 2005, 3:07:07 PM5/13/05
to
On 2005-05-12 17:28:00 -0400, Keith Thompson <ks...@mib.org> said:

> As Jens Toerring pointed out, the "%zu" format is new in C99. That
> means that some systems don't yet support it. (Incidentally, there is
> no "gcc printf man page". printf is part of the runtime library; gcc
> is just the compiler. gcc typically uses the native runtime library
> on a given system, so having a current version of gcc is no guarantee
> that printf() supports "%zu".)
>
> For C90, the best way to print a size_t value is to use "%lu" and cast
> the value to unsigned long. This will *almost* always work in C99 as
> well. The only case where it won't is when size_t is bigger than
> unsigned long (I don't know of any platforms where this is the case)

Just an FYI, for better or worse, it's about to get a lot more common;
64-bit Windows uses the LLP64 convention. i.e.:

int: 32-bits
long: 32-bits
long long: 64-bits
size_t: 64-bits


--
Clark S. Cox, III
clar...@gmail.com

0 new messages