web-dev-qa-db-ja.com

NSIntegerのNSLog / printf指定子?

NSIntegerは、32ビットプラットフォームでは32ビット、64ビットプラットフォームでは64ビットです。常にNSLogのサイズに一致するNSInteger指定子はありますか?

セットアップ

  • Xcode 3.2.5
  • llvm 1.6コンパイラ(これは重要です; gccはこれを行いません)
  • GCC_WARN_TYPECHECK_CALLS_TO_PRINTFオン

それはここでいくつかの悲しみを引き起こしています:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    @autoreleasepool {
        NSInteger i = 0;
        NSLog(@"%d", i);
    }
    return 0;
}

32ビットコードの場合、%d指定子が必要です。しかし、%d指定子を使用すると、64ビット用にコンパイルするときに、代わりに%ldを使用することを示唆する警告が表示されます。

%ldを使用して64ビットサイズに一致させると、32ビットコード用にコンパイルするときに、代わりに%dを使用するように警告するメッセージが表示されます。

両方の警告を一度に修正するにはどうすればよいですか?どちらでも動作する指定子がありますか?

これは、[NSString stringWithFormat:][[NSString alloc] initWithFormat:]にも影響します。

125
Steven Fisher

更新された回答:

現在のXcodeでは、zおよびt修飾子を使用して、すべてのアーキテクチャでNSIntegerおよびNSUIntegerを警告なしで処理できます。

%zdを署名に、%tuを署名なしに、%txを16進数に使用します。

この情報は Greg Parker の厚意により提供されています。


元の回答:

公式の推奨アプローチ は、指定子として%ldを使用し、実際の引数をlongにキャストすることです。

286
Lily Ballard

フォーマッタは、標準のUNIX/POSIX printf関数から取得されます。 %luunsigned longに、%ldをlongに、%lldを使用long longの場合、および%lluunsigned long longの場合。コンソールでman printfを試してくださいが、Macでは不完全です。 Linuxのマンページはより明確です http://www.manpages.info/linux/sprintf.3.html

両方の警告はNSLog(@ "%lu"、(unsigned long)arg)によってのみ修正できます。コードはiOS用に32ビットと64ビットでコンパイルされるため、キャストと組み合わせます。それ以外の場合、コンパイルごとに個別の警告が作成されます。

0
cat