Clean code to printf size_t in C++ (or: Nearest equivalent of C99's %z in C++)


Question

I have some C++ code that prints a size_t:

size_t a;
printf("%lu", a);

I'd like this to compile without warnings on both 32- and 64-bit architectures.

If this were C99, I could use printf("%z", a);. But AFAICT %z doesn't exist in any standard C++ dialect. So instead, I have to do

printf("%lu", (unsigned long) a);

which is really ugly.

If there's no facility for printing size_ts built into the language, I wonder if it's possible to write a printf wrapper or somesuch such that will insert the appropriate casts on size_ts so as to eliminate spurious compiler warnings while still maintaining the good ones.

Any ideas?


Edit To clarify why I'm using printf: I have a relatively large code base that I'm cleaning up. It uses printf wrappers to do things like "write a warning, log it to a file, and possibly exit the code with an error". I might be able to muster up enough C++-foo to do this with a cout wrapper, but I'd rather not change every warn() call in the program just to get rid of some compiler warnings.

1
94
10/10/2009 1:51:09 AM

Accepted Answer

Most compilers have their own specifier for size_t and ptrdiff_t arguments, Visual C++ for instance use %Iu and %Id respectively, I think that gcc will allow you to use %zu and %zd.

You could create a macro:

#if defined(_MSC_VER) || defined(__MINGW32__) //__MINGW32__ should goes before __GNUC__
  #define JL_SIZE_T_SPECIFIER    "%Iu"
  #define JL_SSIZE_T_SPECIFIER   "%Id"
  #define JL_PTRDIFF_T_SPECIFIER "%Id"
#elif defined(__GNUC__)
  #define JL_SIZE_T_SPECIFIER    "%zu"
  #define JL_SSIZE_T_SPECIFIER   "%zd"
  #define JL_PTRDIFF_T_SPECIFIER "%zd"
#else
  // TODO figure out which to use.
  #if NUMBITS == 32
    #define JL_SIZE_T_SPECIFIER    something_unsigned
    #define JL_SSIZE_T_SPECIFIER   something_signed
    #define JL_PTRDIFF_T_SPECIFIER something_signed
  #else
    #define JL_SIZE_T_SPECIFIER    something_bigger_unsigned
    #define JL_SSIZE_T_SPECIFIER   something_bigger_signed
    #define JL_PTRDIFF_T_SPECIFIER something-bigger_signed
  #endif
#endif

Usage:

size_t a;
printf(JL_SIZE_T_SPECIFIER, a);
printf("The size of a is " JL_SIZE_T_SPECIFIER " bytes", a);
60
12/3/2014 10:35:08 AM

The printf format specifier %zu will work fine on C++ systems; there is no need to make it more complicated.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon