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

前端 未结 9 2573
醉梦人生
醉梦人生 2020-12-07 14:20

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

相关标签:
9条回答
  • 2020-12-07 15:07

    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));
    
    0 讨论(0)
  • 2020-12-07 15:11

    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.

    0 讨论(0)
  • 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);
    
    0 讨论(0)
提交回复
热议问题