By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,376 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

64 bit portability, size_t, and printf format strings

P: n/a
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx
describes the integer format modifiers accepted by Microsoft's printf.

http://www.gnu.org/software/libc/man...nversions.html
describes the integer format modifiers accepted by glibc's printf.

They differ (no big surprise), but the difference that's
bugging me today is how size_t integers are handled.
It looks like one has to do %Id (that's a capital i) in windows, and
%zd everywhere else.
This didn't use to matter much, but now that 64 bit portability is
becoming important, source code that used to happily print size_t's
with %d
is hurting. The way I've been dealing with it is to imitate
<inttypes.h>
and define a macro holding the format char for size_t, say

#ifdef MSVC
#define PRIdS "Id"
#else
#define PRIdS "zd"
#endif
....
printf("sizeof(foo_t) is %" PRIdS ".\n", sizeof(foo_t));

but that's awful ugly. I don't suppose we could convince Microsoft to
push out an updated msvcrt.dll that supported the 'z' format modifier
as an alternative to their 'I' modifier?
- Dan

Jun 29 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a


dank wrote On 06/29/06 13:12,:
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx
describes the integer format modifiers accepted by Microsoft's printf.

http://www.gnu.org/software/libc/man...nversions.html
describes the integer format modifiers accepted by glibc's printf.
[...]


You could dodge the issue by using a C90 work-around:

printf ("%lu\n", (unsigned long) sizeof something);

.... on the assumption that no legitimate object will be
larger than ULONG_MAX bytes.

--
Er*********@sun.com

Jun 29 '06 #2

P: n/a
On 29 Jun 2006 10:12:34 -0700, "dank" <da************@gmail.com> wrote
in comp.lang.c:
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx
describes the integer format modifiers accepted by Microsoft's printf.

http://www.gnu.org/software/libc/man...nversions.html
describes the integer format modifiers accepted by glibc's printf.

They differ (no big surprise), but the difference that's
bugging me today is how size_t integers are handled.
It looks like one has to do %Id (that's a capital i) in windows, and
%zd everywhere else.
This didn't use to matter much, but now that 64 bit portability is
becoming important, source code that used to happily print size_t's
with %d
is hurting. The way I've been dealing with it is to imitate
<inttypes.h>
and define a macro holding the format char for size_t, say

#ifdef MSVC
#define PRIdS "Id"
#else
#define PRIdS "zd"
#endif
...
printf("sizeof(foo_t) is %" PRIdS ".\n", sizeof(foo_t));

but that's awful ugly. I don't suppose we could convince Microsoft to
push out an updated msvcrt.dll that supported the 'z' format modifier
as an alternative to their 'I' modifier?
- Dan


The EU has been trying to "convince" Microsoft to comply with the
terms of an antitrust settlement for two years.

Feel free to try to "convince" them to add something to their
implementations merely because it conforms to a non Microsoft specific
standard.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jun 29 '06 #3

P: n/a
dank wrote:
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx
describes the integer format modifiers accepted by Microsoft's printf.

http://www.gnu.org/software/libc/man...nversions.html
describes the integer format modifiers accepted by glibc's printf.

They differ (no big surprise), but the difference that's
bugging me today is how size_t integers are handled.
It looks like one has to do %Id (that's a capital i) in windows, and
%zd everywhere else.
This didn't use to matter much, but now that 64 bit portability is
becoming important, source code that used to happily print size_t's
with %d
is hurting.
That's because you shouldn't print size_t's with %d; assuming that a size_t
will convert to an int "happily" is just silly. At the very least print them
as unsigned. The standard workaround for not having a size_t format
specifier (a great many systems don't, and C89 itself didn't) is to convert
the size_t to an unsigned long and print with %lu. Although this can still
be wrong, it's far less likely to be wrong than %d.
The way I've been dealing with it is to imitate <inttypes.h> and define a
macro holding the format char for size_t, say
#ifdef MSVC
#define PRIdS "Id"
#else
#define PRIdS "zd"
#endif
...
Not bad, but I'd make it %Id and %zd (no need to split them there just
because % is a common character) and make %lu the default, not %zd. That
will only work on systems with a C99-ready C library. You could also add a
check for long long support to use %llu. Not all systems support that
either, but it's more common than %zd support.

To make %lu and %llu work, of course, you need some typedefs for the type
used to print size_t's, so you get something like

printf("sizeof(foo_t) is " SIZE_T_FMT_SPEC ".\n", (size_t_print_type)
(sizeof(foo_t)));
printf("sizeof(foo_t) is %" PRIdS ".\n", sizeof(foo_t));

but that's awful ugly.
The least-effort solution that will get things to work everywhere is allowed
to be ugly. You can alternatively champion the cause of C99 support, but
while worthy, it's not as likely to be successful in the short run.
I don't suppose we could convince Microsoft to push out an updated
msvcrt.dll that supported the 'z' format modifier as an alternative to
their 'I' modifier?


Don't hold your breath. C libraries aren't updated that often. Microsoft's
is no exception. Even *if* Microsoft updated the CRT, it'll be years before
everyone has the updated version. (I do mean years, not some arbitrarily
long time.) The situation is somewhat less dire on Unix systems, but don't
kid yourself into thinking that there's universal support there today.

S.
Jun 29 '06 #4

P: n/a
Skarmander wrote:
dank wrote:

<snip>
The way I've been dealing with it is to imitate <inttypes.h> and define a
macro holding the format char for size_t, say
#ifdef MSVC
#define PRIdS "Id"
#else
#define PRIdS "zd"
#endif
...


Not bad, but I'd make it %Id and %zd (no need to split them there just
because % is a common character)


Well, no, but you may want to add flags and field width and whatnot, so
better to keep the % out of there. Although I don't imagine you'd do much
alternate formatting with a size_t, there's no reason to forbid it.

S.
Jun 29 '06 #5

P: n/a
dank wrote:
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx
describes the integer format modifiers accepted by Microsoft's printf.

http://www.gnu.org/software/libc/man...nversions.html
describes the integer format modifiers accepted by glibc's printf.

They differ (no big surprise), but the difference that's
bugging me today is how size_t integers are handled.
It looks like one has to do %Id (that's a capital i) in windows, and
%zd everywhere else.
No. It should be %Iu on Windows and %zu everywhere else. Remember that
size_t is an unsigned integer type!
This didn't use to matter much, but now that 64 bit portability is
becoming important, source code that used to happily print size_t's
with %d
is hurting.


Yes. However on all the 64-bit compilers I've used so far, 'unsigned
long' moved to 64 bits, so you could still use %lu and cast the size_t
value to unsigned long.

--
Simon.
Jun 30 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.