将Xcode更新为5.1时,错误"从指向较小类型'int'的指针转换为EAGLView.mm中的信息"(5B130a)

nvg*_*g58 21 iphone cocos2d-x xcode5 ios7.1 cocos2d-x-2.x

昨天,我将Xcode更新到最新版本(5.1 (5B130a))以兼容iOS 7.1.然后我构建我的项目,当选择64位模拟器(例如:iPhone Retina 4英寸64位)时,我"Cast from pointer to smaller type 'int' loses information"EAGLView.mmfile(line 408)中得到错误.

我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)

Kai*_*udi 41

显然,Xcode 5.1及更高版本中的clang版本对于源代码中潜在的32位与64位不兼容性的严格程度要比旧版本的版本更严格.说实话,我认为,clang在这里限制太多了.一个理智的编译器可能会在这样的行上发出警告,但绝不会抛出错误,因为这段代码没有错,它只是可能容易出错,但可以完全有效.

原始代码是

ids[i] = (int)touch;
Run Code Online (Sandbox Code Playgroud)

IDS是整数数组和触摸是一个指针.

在64位建立一个指针为64bit(违背一个32位的构建,它是32位),而一个int是32位,所以该分配存储在一个32位的存储一个64位的值,这可能导致信息丢失.

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

ids[i] = touch;
Run Code Online (Sandbox Code Playgroud)

但是,有问题的实际代码包含对int的显式c样式转换.这个显式的演员清楚地告诉编译器"闭嘴,我知道这段代码看起来不正确,但我知道我在做什么".

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

ids[i] = (int)(size_t)touch;
Run Code Online (Sandbox Code Playgroud)

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

  • 将 `(int)(size_t)boo` 转换为 `(int)boo` 解决了我的问题。谢谢! (3认同)

Meh*_*tri 9

替换ids[i] = (int)touch;ids[i] = (uintptr_t)touch;

这个对我有用.

  • 这使编译错误消失,但它改变了代码的运行时行为.原始代码铸造了一个指向int的指针.您的代码现在取消引用指针,并且不再将指针地址本身存储在int中,而是指向它指向的值.为了实现旧的Xcode 5.0行为,代码现在应该是ids [i] =(int)(size_t)touch; (11认同)
  • 这个答案绝对不正确.不是使用UITouch的内存位置的地址,而是对每个UITouch对象都是唯一的,这个答案将使用UITouch对象的前4个字节.前4个字节很可能是虚函数表指针的前4个字节,每个类只能是唯一的.不好. (5认同)

Muh*_*Ali 6

我也遇到了这个问题.

ids[i] = (int)touch; //错误发生在这里=>我将此更改为以下.

ids[i] = (uintptr_t)touch;
Run Code Online (Sandbox Code Playgroud)

然后我可以继续编译.也许你也可以尝试一下.


小智 2

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

您只需在“构建设置”中更改架构以支持 32 位编译

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

希望能帮助到你。