32ビットアーキテクチャでGCCコンピレーションで次の警告がありますが、64ビットアーキテクチャでそのような警告はありません

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

  •  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.

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