32と64のプラットフォームでsizeofを使用したprintf:プラットフォームに依存しない方法でフォーマットコードを処理する方法

StackOverflow https://stackoverflow.com/questions/1403074

  •  05-07-2019
  •  | 
  •  

質問

プログラムで使用されるメモリ量を出力するコードがあります。行はこれに似ています:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

anIntVariableは、double配列の要素数を表すint変数です。とにかく、32ビットシステムでは問題がなかったが、64ビットシステムでは"%u"の使用に関するコンパイラの警告が表示されます。符号なし長整数の場合。 "%lu"の使用形式コードは64ビットでの問題を修正しますが、型がunsigned intに戻るため、32ビットではコンパイラーが文句を言うためです。実際、sizeof(double)は32ビットシステムと64ビットシステムで異なる値を返すことがわかりました。コードを32ビットから64ビットに変換するためのいくつかのWebページガイドを見つけましたが、単に相互に変換するのではなく、両方で機能するコードが欲しいです。

この行をプラットフォームに依存しない方法で記述する方法は?プリプロセッサディレクティブを使用してそれを行うことができる多くの方法を知っていますが、それはハックのようです。確かに、私が気付いていないエレガントな方法があります。

役に立ちましたか?

解決

ポータブルprintf識別子は、インクルードファイル inttypes.h で提供されます。

このインクルードファイルには、特定のランタイム用の多くの移植可能な識別子があります。たとえば、PRIuPTRが必要です。これは、「 PR intf I 識別子 u ポインタのサイズまでのサイズで署名」を意味します。

例は次のようになります。

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

GCC 4.3を使用した64ビットLinuxでの結果( int anIntVariable = 1 ):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

完全を期すために、scanfの識別子もあります。プレフィックスはSCNです。

他のヒント

sizeofの戻り値はsize_tです。 C99準拠のコンパイラを使用している場合、 %zd %zu を使用できるようです。

D'oh:もちろん%zu (署名なし)。どうもありがとう。

まず、"%"と一致させる必要があります。印刷する実際のデータ型の指定子。 sizeof は、データ型 size_t を返しますが、「%d」を使用してfloatを印刷しようとするべきではありません。指定子、"%u"を指定してsize_tを印刷しないでください。または"%d"または実際にはsize_tを意味しないもの。

他の返信では、新しいコンパイラ("%z"およびPRIu32)でこれを処理するためのいくつかの良い方法を提供していますが、これを行う方法は、size_tをunsigned longにキャストしてから、 "%lu":

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

これは、size_tがlongよりも広いシステムでは機能しませんが、そのようなシステムは知りません。標準で許可されているかどうかもわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top