1. ホーム
  2. c++

[解決済み] C++ で size_t を printf するためのきれいなコード (または: C99 の %z に最も近い C++ のコード)

2022-12-07 23:06:33

質問

C++のコードで size_t :

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

32ビットと64ビットの両方のアーキテクチャで、警告を出さずにコンパイルできるようにしたいです。

もしこれがC99だったら、私は printf("%z", a); . しかし、AFAICTは %z はどの標準的なC++の方言にも存在しません。 ですから、代わりに、私は

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

というのは実に醜い。

を印刷する機能がない場合 size_t を印刷する機能がないのであれば、printf のラッパーなどを書いて、適切なキャストを size_t に適切なキャストを挿入して、良い警告を維持しながら偽のコンパイラ警告を排除するような、printf のラッパーか何かを書くことは可能でしょうか。

何かアイデアはありますか?


編集 私がprintfを使用している理由を明確にするために。私は比較的大きなコードベースを持っていて、それを整理しているところです。 それは、警告を書き、それをファイルに記録し、場合によってはエラーでコードを終了する"といったことを行うためにprintfラッパーを使用しています。 cout ラッパーでこれを行うために十分な C++ フーを呼び出すことができるかもしれませんが、コンパイラの警告を取り除くためだけにプログラム内のすべての warn() 呼び出しを変更するのは避けたいのです。

どのように解決するのですか?

ほとんどのコンパイラは、独自の仕様で size_tptrdiff_t の引数は、例えば Visual C++ ではそれぞれ %Iu と %Id を使いますが、gcc では %zu と %zd を使えるようになると思います。

マクロを作ればいいんじゃない?

#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

使用方法

size_t a;
printf(JL_SIZE_T_SPECIFIER, a);
printf("The size of a is " JL_SIZE_T_SPECIFIER " bytes", a);