NSInteger的NSLog/printf说明符?

Ste*_*her 126 cocoa objective-c nslog nsinteger 32bit-64bit

A 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;
}
Run Code Online (Sandbox Code Playgroud)

对于32位代码,我需要说明%d符.但是,如果我使用说明%d符,我在编译64位时会收到警告,建议我使用%ld.

如果我使用%ld匹配64位大小,编译32位代码时,我会收到警告,建议我使用%d.

如何一次修复这两个警告?是否有我可以使用的说明符?

这也影响[NSString stringWithFormat:]和[[NSString alloc] initWithFormat:].

Lil*_*ard 288

更新的答案:

使用当前的Xcode,您可以在所有体系结构上使用z和t修饰符来处理NSInteger并且NSUInteger不需要警告.

您想要%zd用于signed,%tufor unsigned和%txfor hex.

这些信息来自Greg Parker.


原始答案:

该负责人建议的方法是使用%ld为你的符,并且实际参数转换为long.

  • 这绝对是要走的路,但我想我可能会使用`static inline NSIntToLong(NSInteger i){return(long)i;}`.这避免了完全禁用类型检查(即,如果i的类型改变). (6认同)
  • @ steven-fisher的好思维.避免警告:`static inline long NSIntToLong(NSInteger i){return(long)i;}` (3认同)
  • 您还可以创建NSNumber并记录它.`NSLog(@"%@",@(mynsint));`http://stackoverflow.com/questions/20355439/nsinteger-and-nsuinteger-in-a-mixed-64bit-32bit-environment (3认同)
  • 从Xcode 9.3开始,当使用NSInteger作为带有`%zd`的格式参数时会出现警告:`'NSInteger'类型的值不应该用作格式参数; 添加一个显式的强制转换为'long'而不是' (3认同)
  • @KevinBallard这不应该是一个严重的性能问题.不管怎样,你不应该在生产代码中使用大量的NSLog.如果由于某种原因必须记录大量内容,请在单独的线程上进行. (2认同)