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
C++11
C++11 imports C99 so std::printf
should support the C99 %zu
format specifier.
C++98
On most platforms, size_t
and uintptr_t
are equivalent, in which case you can use the PRIuPTR macro defined in <cinttypes>
:
size_t a = 42;
printf("If the answer is %" PRIuPTR " then what is the question?\n", a);
If you really want to be safe, cast to uintmax_t
and use PRIuMAX
:
printf("If the answer is %" PRIuMAX " then what is the question?\n", static_cast<uintmax_t>(a));
The fmt library provides a fast portable (and safe) implementation of printf
including the z
modifier for size_t
:
#include "fmt/printf.h"
size_t a = 42;
int main() {
fmt::printf("%zu", a);
}
In addition to that it supports Python-like format string syntax and captures type information so that you don't have to provide it manually:
fmt::print("{}", a);
It has been tested with major compilers and provides consistent output across platforms.
Disclaimer: I'm the author of this library.
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);