2

symbol.c:関数'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 }

そして、SYMBOLは次のように定義されます。

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ビットアーキテクチャで警告なしにコンパイルできるように、これを取り除くにはどうすればよいですか?

その解決策は何でしょうか?

4

2 に答える 2

4

の形式として%zuではなくを使用すると、32ビットビルドと64ビットビルドの両方で正しい動作が得られます(警告は表示されません)。%ldsize_t

何らかの理由で使用できない場合%zu(古いコンパイラや非標準のコンパイラなど)、次のようなことができます。

#ifdef __LP64__ // if 64 bit environment
#define FMT_SIZE_T "llu"
#else
#define FMT_SIZE_T "lu"
#endif

次に、size_t型の何かでprintfを使用する必要がある場合は、次のように実行できます。

printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *));
于 2010-03-11T15:20:36.117 に答える
2

Linux上で%luのC89準拠(またはgcc-c89-warnings準拠)の唯一の形式であることがわかりました。size_tglibcの下でsize_tは、常にそうlong unsigned intであるように思われるので、そこ%luでは適切です。

特に、gcc-4.4.3で、および-std=c89 -pedanticについて-std=c89 -Wall警告することがわかりました。彼らが期待しているので、C99タイプは理にかなっています。%llu%lldlong long

悲劇的なことsize_tに、プラットフォームに依存しないC89準拠の方法でを印刷する方法はありません。C89では、すべての printf形式が特定のプリミティブ型(、、など)を参照しますlongintすべてのC方言でsize_tは、プラットフォームに依存します(longまたはintまたは何か他のものである可能性があります)。

いつものように、マイクロソフトはあなたに独自の特別なモンキーレンチを投げます。Windowsコンパイル環境はひどく変更されたC89です:それはありますが、 printf修飾子はlong longありません。ll窓の土地では、に%lluなり%I64u、に%zuなり%Iuます。

ラボのコードベースで次のものを使用することになりました。

#ifdef _WIN32
#define PRIuZ "Iu"
#そうしないと
#define PRIuZ "lu"
#endif

使用する:

printf( "%" PRIuZ "\ n"、sizeof(struct foo));

私はC99の定義から名前をモデル化しましたinttypes.h

余談ですが、私のバージョンのwin64 mingw-gcc(4.4.5 20100527(プレリリース)[svn / rev.159909 --mingw-w64 / oz])、プラス-Wallまたは-pedantic、は、を印刷するときに常に警告しsize_tます。%I64uそれは、と%Iuが非標準であると不平を言います、そしてそれ%luは正しくありません。コンパイラがマイクロソフトの狂気によって正しくつまずいたようです。私はそれを気にしないようにするために使用-pedantic -Wformat=0しなければなりませんでした%Iu

于 2011-03-31T02:49:06.713 に答える