开发者

Why does only NSLog warn me about using the %lu string format specifier for NSUInteger?

开发者 https://www.devze.com 2023-02-11 13:57 出处:网络
For some reason, I get a compilation error 开发者_StackOverflow社区when I try to do the following:

For some reason, I get a compilation error 开发者_StackOverflow社区when I try to do the following:

NSLog(@"row: %lu", indexPath.row);

where row is of type NSUInteger. The error I get is

Conversion specifies type 'unsigned long' but the argument has type 'NSUInteger' (aka 'unsigned int')

I can do the following with no compilation errors:

NSString * string = [NSString stringWithFormat:@"row: %lu", indexPath.row];

I'm using the exact same format string and substitution argument in both cases, but why does NSLog freak out while -stringWithFormat: seems to be perfectly content? My compiler is LLVM 1.6.


All devices that iOS currently runs on are 32-bit. If you want to silence the warning:

NSLog(@"row: %lu", (unsigned long)indexPath.row);

[Edit: As of the iPhone 5s, it is no longer true that iOS is always 32-bit.]


I've run into this same issue, and although @Wevah is correct and his answer works just fine, there's another option that doesn't require any code changes. See the following Apple documentation for details:

String Programming Guide | Platform Dependencies

64-Bit Transition Guide for Cocoa | Building 32-Bit Like 64-Bit

The NS_BUILD_32_LIKE_64 preprocessor macro is quite helpful. You can set it in your Xcode project settings (under GCC_PREPROCESSOR_DEFINITIONS) or just put #define NS_BUILD_32_LIKE_64 1 in your precompiled header (.pch) file. In my app, this eliminated 11 warnings without any code changes.

This works because unsigned int and unsigned long are the same size (4 bytes) on iOS, so changing the typedef of NSUInteger makes the compiler (and the developer) happy, but the hardware doesn't care, since it's just doing integer math in both cases. :-)


Apple documentation recommends casting the 64 bit value to a 32 bit value using %lu and %ld. This poses a problem if you actually use the extra 32 bits. Format strings %qu and %qd specify a 64 bit value (unsigned and signed respectively). If you want code that will compile in either mode, then values declared as NSUInteger or NSInteger will have to be cast to a UInt64 or SInt64 in the parameter list to avoid the warning.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号