Clean code to printf size_t in C++ (or: Nearest equivalent of C99's %z in C++)
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_t
s 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_t
s 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.
Solution 1:
The printf
format specifier %zu
will work fine on C++ systems; there is no need to make it more complicated.
Solution 2:
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);