32ビットアーキテクチャでGCCコンピレーションで次の警告がありますが、64ビットアーキテクチャでそのような警告はありません
-
19-09-2019 - |
質問
symbol.c:infunce 'symbol_fprint':
symbol.c:1209: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c: In function 'symbol_FPrintOtter':
symbol.c:1236: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1239: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1243: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1266: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c
1198 #ifdef CHECK
1199 else {
1200 misc_StartErrorReport();
1201 misc_ErrorReport("\n In symbol_FPrint: Cannot print symbol.\n");
1202 misc_FinishErrorReport();
1203 }
1204 #endif
1205 }
1206 else if (symbol_SignatureExists())
1207 fputs(symbol_Name(Symbol), File);
1208 else
1209 fprintf(File, "%ld", Symbol);
1210 }
シンボルは次のように定義されています。
typedef size_t SYMBOL
「%LD」を「%Zu」に置き換えたとき、次の警告がありました。
symbol.c: In function 'symbol_FPrint':
symbol.c:1209: warning: ISO C90 does not support the 'z' printf length modifier
注:ここから2010年3月26日に編集され、上記の問題と類似しているため、次の問題が追加されました。
次の声明があります:
printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
Precedence[Index],S->props,S->name, S->length);
64ビットアーキテクチャでコンパイル中に得られる警告は次のとおりです。
format ‘%4d’ expects type ‘int’, but argument 5 has type ‘size_t’
パラメーターの定義は次のとおりです。
NAT props;
typedef unsigned int NAT;
32および64ビットアーキテクチャで警告なしにコンパイルできるように、これを取り除くにはどうすればよいですか?
その解決策は何ですか?
解決
使用する %zu
それよりも %ld
フォーマットとして size_t
そして、32ビットと64ビットの両方のビルドで正しい動作(および警告なし)が得られます。
何らかの理由で使用できない場合 %zu
(例えば、古いまたは標準以外のコンパイラ)、次のようなことができます。
#ifdef __LP64__ // if 64 bit environment
#define FMT_SIZE_T "llu"
#else
#define FMT_SIZE_T "lu"
#endif
次に、somethign of yty size_tでprintfを使用する必要がある場合、これを行うことができます。
printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *));
他のヒント
私は見つけます %lu
の唯一のC89準拠(または、GCC-C89-ornings-compliant)形式であること size_t
, 、Linuxで。 glibcの下、 size_t
いつもそうあるようです long unsigned int
, 、 それで %lu
そこに適切です。
特に、GCC-4.4.3で -std=c89 -pedantic
また -std=c89 -Wall
警告します %llu
と %lld
. 。彼らが期待しているので、理にかなっています long long
, 、C99タイプ。
悲劇的には、印刷する方法はありません size_t
プラットフォームに依存しないC89準拠の方法で。 C89で、 全て printf
形式は特定のプリミティブタイプを指します(long
, int
, など)、しかし 全て C方言、 size_t
プラットフォームに依存しています(そうかもしれません long
また int
または、他の何か)。
いつものように、Microsoftはあなた自身の特別な猿のレンチを投げます。 Windowsコンピレーション環境は、改造されたひどいC89です。 long long
, 、しかしいいえ ll
printfモディファイア。窓の土地で、 %llu
なります %I64u
と %zu
なります %Iu
.
ラボのコードベースで以下を使用することになりました。
#ifdef _WIN32 #define PRIuZ "Iu" #else #define PRIuZ "lu" #endif
使用する:
printf("%"PRIuZ"\n", sizeof(struct foo));
C99の定義から名前をモデル化しました inttypes.h
.
さておき:Win64 MINGW-GCCの私のバージョン(4.4.5 20100527(Prerelease)[SVN/Rev.159909-MINGW-W64/OZ])、プラス -Wall
また -pedantic
, いつも 印刷するときに警告します size_t
. 。それはそれを不平を言っています %I64u
と %Iu
非標準です %lu
間違っています。コンパイラは、Microsoftの狂気によって正しくつまずかれているようです。私は使わなければなりませんでした -pedantic -Wformat=0
それを泣かないようにするために %Iu
.