【问题标题】:Cocoa: NSUInteger and UInt32 both defined as 32 bit unsigned integer. So why the warnings?Cocoa:NSUInteger 和 UInt32 都定义为 32 位无符号整数。那么为什么会出现警告呢?
【发布时间】:2013-02-18 08:19:14
【问题描述】:

查看标题,我可以看到对于我正在编译的 64 位系统,NSUInteger 和 UInt32 都定义为 32 位无符号整数,那么为什么 Xcode 在我的警告中声称精度下降将一个分配给另一个?

“隐式转换丢失整数精度:'NSUInteger' (aka 'unsigned long') 到 'UInt32' (aka 'unsigned int')”

我可以看到警告将一个称为“long”,一个称为“int”,但由于它们在此系统上都解析为相同的 32 位无符号整数,因此应该不会损失精度。

它实际上并没有引起任何问题,但似乎我可能误解了一些东西,所以想更好地理解。

有这个问题,但它解决了安全问题,而不是“为什么”: Can I safely store UInt32 to NSUInteger?

【问题讨论】:

  • 可能是因为 NSUInteger 在其他系统上可以变成 64 位长。

标签: objective-c xcode cocoa osx-lion nsuinteger


【解决方案1】:

NSUIntegerNSInteger 甚至可以在 iOS 和 OSX 中使用。

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
    typedef long NSInteger; 
    typedef unsigned long NSUInteger;
#else 
    typedef int NSInteger; 
    typedef unsigned int NSUInteger;
#endif

iOS 是 32 位设备,而 OSX 是 64 位(早期的 OSX 是 32 位,甚至您可以选择为 32 位操作系统制作应用程序),因此它包含一个 if-else directive,基于它设置。

在 OSX 中,我总是使用 %ldNSInteger,但在 iOS 中它必须是 %d

如果您将%d 用于NSInteger,则会显示警告 Loses integer precision。

【讨论】:

  • 在 OSX 下编译 32 位时会怎样?
  • 好的,谢谢 Anoop。那么关于编译器是如何工作的,这是否意味着它会在 解析 if-else 指令之前计算警告,所以还没有意识到这是不必要的?
  • @trojanfoe:在这种情况下,它将是 32 位的,就像 if-else 指令中的那样
  • 好的,那么“OSX 是 64 位”的说法是不准确的。
【解决方案2】:

在 64 位 OS X 平台上:

  • NSUInteger 定义为unsigned long,并且
  • unsigned long 是一个 64 位无符号整数。

所以UInt32NSUInteger 确实具有相同的大小,这解释了编译器警告。

另请参阅“基础数据类型参考”中的NSUInteger

在构建 32 位应用程序时,NSUInteger 是一个 32 位无符号 整数。 64 位应用程序将 NSUInteger 视为 64 位无符号 整数。

备注: 64 位 OS X(与许多 Unix 和类 Unix 系统一样)使用 LP64 数据模型,这意味着 long指针 是 64 位的。 64 位 Windows 使用 IL32P64 数据模型,其中 long 为 32 位,pointers 为 64 位。

【讨论】:

  • 谢谢,我想我在解释 MacTypes.h 中的标头方面是个菜鸟: UInt32 32-bit unsigned integer ... typedef unsigned int UInt32;在 NSObjCRuntime.h 中:#if LP64 || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 typedef long NSInteger; typedef unsigned long NSUInteger;
  • @JoeyFourSheds:是的,这正是定义它的地方。 __LP64__ 在 64 位平台上为真,NSUInteger 被定义为 unsigned long,而 unsigned long 在 64 位平台上有 64 位! - 由于 Uint32 只有 32 位,因此可能存在精度损失。
  • 谢谢。 (对于凌乱的评论感到抱歉,似乎无法在评论中换行,因此每次我习惯性地点击“返回”时,它都会发布大约 6 次!)。
  • @JoeyFourSheds:不客气。我添加了一些关于long 大小的信息。
猜你喜欢
  • 1970-01-01
  • 2011-05-17
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 2018-08-06
  • 2019-06-21
相关资源
最近更新 更多