[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

size_t in inttypes.h

ImpalerCore

5/26/2011 8:23:00 PM

One of the pet peeves of mine for a long time is printing size_t
values, because C99 has the nice little 'z' modifier, but in the
compiler I use for embedded work, these C99 features is not
supported. In those situations, the recommendation is to cast the
size_t value to unsigned long, and use %lu. The issue is that there
are two different source styles for the two compiler environments, and
I'd like to make a single style work for both compiler standards. Of
course one could resort to use %lu and casting in both environments,
but I don't like it.

The two styles clash because I am writing a library for which I'd like
to maintain support for C90 and C99 compilers, and many of the
examples use size_t variables, either directly or indirectly through a
library function's return value or argument. I don't want to maintain
two separate examples just because the rules for printing a size_t
differ.

I currently have a wrapper for <stdint.h> and <inttypes.h> that I use
to define C90 versions of the intN_t and uintN_t types, as well as
their fprintf macro format specifiers like PRIu32. If one lacks a
native <inttypes.h> header file, one can still manually define them by
looking at <limits.h>.

\code snippet
.... stdint.h definitions above like ...
#define INT32_MAX (2147483647L)
....

#if defined(_MSC_VER) || defined(_WIN32)
# define PRId32 "I32d"
# define PRIi32 "I32i"
#else
# if (INT32_MAX == LONG_MAX)
# define PRId32 "ld"
# define PRIi32 "id"
# elif (INT32_MAX == INT_MAX)
# define PRId32 "d"
# define PRIi32 "i"
# elif (INT32_MAX == SHRT_MAX)
# define PRId32 "hd"
# define PRIi32 "hi"
# else
# error "Platform not supported"
# endif
#endif
\endcode

One way to provide a single viable method to format a size_t integer
is to create an <inttypes.h> compatible fprintf macro format
specifier, let's call it PRI[ouxX]SIZE. If C99 is present, one can
simply defer to use "z" as the leading modifier, but if it's not
present, one can again use <limits.h> to determine the correct
modifier to apply.

\code snippet
#if (defined(__STDC__) && defined(__STDC_VERSION__))
# if (__STDC__ && __STDC_VERSION__ >= 199901L)
# define PRIoSIZE "zo"
# define PRIuSIZE "zu"
# define PRIxSIZE "zx"
# define PRIXSIZE "zX"
# endif
#else
/* ULLONG_MAX is defined in my wrapper if 64-bit integer extensions
are detected, even if it's not a C99 compiler. */
# if defined(ULLONG_MAX) && (SIZE_MAX == ULLONG_MAX)
# define PRIoSIZE "llo"
# define PRIuSIZE "llu"
# define PRIxSIZE "llx"
# define PRIXSIZE "llX"
# elif (SIZE_MAX == ULONG_MAX)
# define PRIoSIZE "lo"
# define PRIuSIZE "lu"
# define PRIxSIZE "lx"
# define PRIXSIZE "lX"
# elif (SIZE_MAX == UINT_MAX)
# define PRIoSIZE "o"
# define PRIuSIZE "u"
# define PRIxSIZE "x"
# define PRIXSIZE "X"
# elif (SIZE_MAX == USHRT_MAX)
# define PRIoSIZE "ho"
# define PRIuSIZE "hu"
# define PRIxSIZE "hx"
# define PRIXSIZE "hX"
# else
# error "Platform not supported"
# endif
#endif
\endcode

Then in theory, one can use the following to print a size_t value in
either C90 or C99.

\code snippet
#include <stdio.h>
#include "my_inttypes.h"

int main( void )
{
printf( "sizeof int = %" PRIuSIZE "\n", sizeof (int) );
return 0;
}
\endcode

The only kicker is that SIZE_MAX is not defined in C90, so one must
either rely on an auto-configuration script to detect SIZEOF_SIZE_T
that you can infer SIZE_MAX from, or worse have a human define it
manually. Definitions like ((size_t)-1) don't seem to work with the
preprocessor well.

I must say that I find the idea of PRIuSIZE and friends tempting, just
to have a uniform method of printing size_t values in library API
examples that work in C90 and C99, and hopefully C1X. I'm not
familiar with the history of the fprintf macro specifiers, so I wonder
why PRIuSIZE and friends were not included, when it's an obvious
candidate due to a lack of an exact modifier to a format specifier.
In my opinion, it's much easier to define a stdint.h/inttypes.h
wrapper for a C90 compiler and use PRIuSIZE than to create/modify a
printf implementation to accept %zu.

Even if I do like and choose to use my own PRIuSIZE creation in my
library examples, I imagine it's likely to get flak from it being
unidiomatic. Am I destined to cast my size_t values to (unsigned
long) forever?

Just for my curiosity's sake, any reason why stdint.h and inttypes.h
were separated in the first place? After looking at inttypes.h, it
doesn't really define any integer types as it's name implies, mostly
format specifiers. It seems logical to just graft inttypes.h into
stdint.h and put it all in one place.

Thanks for any feedback,
John D.
4 Answers

Seebs

5/26/2011 8:34:00 PM

0

On 2011-05-26, ImpalerCore <jadill33@gmail.com> wrote:
> The two styles clash because I am writing a library for which I'd like
> to maintain support for C90 and C99 compilers, and many of the
> examples use size_t variables, either directly or indirectly through a
> library function's return value or argument. I don't want to maintain
> two separate examples just because the rules for printing a size_t
> differ.

Ugh! Yes.

I'm still mostly doing the (unsigned long) thing, but I am not sure this
is the right choice, it's just a habit.

> Just for my curiosity's sake, any reason why stdint.h and inttypes.h
> were separated in the first place? After looking at inttypes.h, it
> doesn't really define any integer types as it's name implies, mostly
> format specifiers. It seems logical to just graft inttypes.h into
> stdint.h and put it all in one place.

I believe the answer is:

Historically, it was <inttypes.h> and it was a Unixism or something to
that effect. Then the idea occurred that <stdint.h> defining just the
types would provide functionality suitable for freestanding environments,
or something to that effect.

.... I was actually there when it happened, but it was over a decade ago
and my memory isn't good.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seeb... <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/...(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Keith Thompson

5/26/2011 8:37:00 PM

0

ImpalerCore <jadill33@gmail.com> writes:
[...]
> Just for my curiosity's sake, any reason why stdint.h and inttypes.h
> were separated in the first place? After looking at inttypes.h, it
> doesn't really define any integer types as it's name implies, mostly
> format specifiers. It seems logical to just graft inttypes.h into
> stdint.h and put it all in one place.

C99 7.8p1:
The header <inttypes.h> includes the header <stdint.h> and
extends it with additional facilities provided by hosted
implementations

<inttypes.h> provides macros to be used with *printf() and *scanf(),
which are only required for hosted implementations. <stdint.h>
is required for both hosted and freestanding implementations.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

ImpalerCore

5/27/2011 3:42:00 PM

0

On May 26, 4:33 pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2011-05-26, ImpalerCore <jadil...@gmail.com> wrote:
>
> > The two styles clash because I am writing a library for which I'd like
> > to maintain support for C90 and C99 compilers, and many of the
> > examples use size_t variables, either directly or indirectly through a
> > library function's return value or argument.  I don't want to maintain
> > two separate examples just because the rules for printing a size_t
> > differ.
>
> Ugh!  Yes.
>
> I'm still mostly doing the (unsigned long) thing, but I am not sure this
> is the right choice, it's just a habit.

Could you see yourself using PRIuSIZE and friends if it were ever to
get standardized? There's pretty good precedent for other types that
lack exact fprintf modifiers. The only question is whether the
committee would see it as unnecessary redundancy since C99 already
defined a format modifier "z", which unfortunately suffers from
spurious support in the C community.

Best regards,
John D.

Seebs

5/27/2011 7:36:00 PM

0

On 2011-05-27, ImpalerCore <jadill33@gmail.com> wrote:
> Could you see yourself using PRIuSIZE and friends if it were ever to
> get standardized? There's pretty good precedent for other types that
> lack exact fprintf modifiers. The only question is whether the
> committee would see it as unnecessary redundancy since C99 already
> defined a format modifier "z", which unfortunately suffers from
> spurious support in the C community.

I would probably not, just because I'd expect anyone who had it to already
handle %z. I just wish people had been better about supporting z. :)

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seeb... <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/...(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.