27

昨天,我将 Xcode 更新到最新版本(5.1 (5B130a))以兼容iOS 7.1. Then I build my project, I get the error "Cast from pointer to smaller type 'int' loses information"in EAGLView.mmfile ( line 408) when 64-bit simulators (eg: iPhone Retina 4-inch 64-bit) is selected.

我正在使用cocos2d-x-2.2.2. 在我更新 Xcode 之前,我的项目仍然可以在所有设备上正常构建和运行。

感谢所有推荐。

更新:今天,我下载了最新版本的 cocos2d-x(cocos2d-x 2.2.3)。但问题仍然存在。

这是发生该错误的一些代码:

/cocos2d-x-2.2.2/cocos2dx/platform/ios/EAGLView.mm:408:18: Cast from pointer to smaller type 'int' loses information

// Pass the touches to the superview
#pragma mark EAGLView - Touch Delegate
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (isKeyboardShown_)
    {
        [self handleTouchesAfterKeyboardShow];
        return;
    }

    int ids[IOS_MAX_TOUCHES_COUNT] = {0};
    float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};

    int i = 0;
    for (UITouch *touch in touches) {
        ids[i] = (int)touch;     // error occur here
        xs[i] = [touch locationInView: [touch view]].x * view.contentScaleFactor;;
        ys[i] = [touch locationInView: [touch view]].y * view.contentScaleFactor;;
        ++i;
    }
    cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesBegin(i, ids, xs, ys);
}
4

6 回答 6

48

显然,Xcode 5.1 及更高版本中的 clang 版本对源代码中潜在的 32 位与 64 位不兼容问题比旧的 clang 版本更加严格。老实说,我认为,clang 在这里过于严格。理智的编译器可能会在这样的行上抛出警告,但绝不应该抛出错误,因为这段代码没有错,它只是潜在地容易出错,但可以完全有效。

原始代码是

ids[i] = (int)touch;

ids是一个整数数组,而touch一个指针。

在 64 位构建中,指针是 64 位(与 32 位构建相反,它是 32 位),而 int 是 32 位,因此此分配将 64 位值存储在 32 位存储中,这可能会导致信息丢失。

因此,编译器为类似的行抛出错误是完全有效的

ids[i] = touch;

然而,有问题的实际代码包含显式的 c 样式转换为 int。这个显式转换清楚地告诉编译器“闭嘴,我知道这段代码看起来不正确,但我知道我在做什么”。

所以编译器在这里非常挑剔,让代码再次编译并仍然让它显示与 Xcode 5.0 中完全相同的行为的正确解决方案是首先转换为大小与指针匹配的整数类型,然后然后对我们真正想要的 int 进行第二次强制转换:

ids[i] = (int)(size_t)touch;

我在这里使用 size_t ,因为无论平台如何,它始终具有与指针相同的大小。long long 不适用于 32 位系统,long 不适用于 64 位 Windows(而 64 位 Unix 和类似 Unix 的系统(如 OS X)使用 LP64 数据模型,其中 long 是 64 位,64 位 Windows 使用 LLP64 数据模型,其中 long 的大小为 32 位(http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models))。

于 2014-11-20T16:20:17.207 回答
7

我也遇到这个问题。

ids[i] = (int)touch;// 此处发生错误 => 我将其更改为下面。

ids[i] = (uintptr_t)touch;

然后我可以继续编译。也许你也可以试试这个。

于 2014-04-03T06:43:00.850 回答
2

XCode 5.1 将所有架构更改为 64 位。

您可以在 Build Settings 中更改架构以支持 32 位编译

  • 在架构中使用 $(ARCHS_STANDARD_32_BIT) 而不是 $(ARCHS_STANDARD)
  • 在有效架构中删除arm64

希望能帮助到你。

于 2014-03-18T09:00:01.117 回答
1

您可以通过替换这行代码来修复此错误。

ids[i] = (uint64_t)touch;

您应该基于 64 位构建系统进行类型转换,因为类型“int”仅支持 -32768 ~ 32768。

于 2016-05-21T14:27:46.983 回答
0

当然,解决方案是将 id 的类型从 int 更改为足够大以容纳指针的类型。

我不熟悉 XCode,但解决方案应该如下所示:

将 id 的声明更改为:

intptr_t ids[IOS_MAX_TOUCHES_COUNT];

以及产生错误的行:

ids[i] = (intptr_t)touch;

上面的大多数“解决方案”在转换为较小的类型时可能会丢失部分指针地址。如果该值再次用作指针,那将被证明是一个非常糟糕的主意。

于 2015-03-11T13:03:57.727 回答
-2
ids[i] = (int)touch; put * and check it.
ids[i] = *(int *)touch;
于 2015-09-09T06:08:14.630 回答