Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

printf

size-t

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.
like image 935
Justin L. Avatar asked Oct 10 '09 01:10

Justin L.


People also ask

What is %z in printf?

We should use “%zu” to print the variables of size_t length. We can use “%d” also to print size_t variables, it will not show any error. The correct way to print size_t variables is use of “%zu”. In “%zu” format, z is a length modifier and u stand for unsigned type. The following is an example to print size_t variable.

What is zu format specifier?

The %zu format specifier was introduced specifically for size_t , so as to clear the confusion of having to choose in between the unsigned integer specifiers %u , %lu , and more recently %llu .


2 Answers

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

like image 57
Will Avatar answered Sep 29 '22 18:09

Will


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); 
like image 29
dalle Avatar answered Sep 29 '22 17:09

dalle