昨天,我将Xcode更新为最新版(5.1 (5B130a))
以与iOS 7.1
兼容。然后我构建我的项目,当{64}模拟器(例如:iPhone Retina 4英寸64位)被选中时,我在"Cast from pointer to smaller type 'int' loses information"
文件(EAGLView.mm
)中得到错误line 408
。 / p>
我正在使用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);
}
答案 0 :(得分:35)
显然,Xcode 5.1及更高版本中的clang版本对于源代码中潜在的32位与64位不兼容性的严格程度要高于旧版本的版本。 说实话,我认为,clang在这里限制太多了。一个理智的编译器可能会在这样的行上发出警告,但绝不应该抛出错误,因为这段代码没有错,它只是可能容易出错,但可以完全有效。
原始代码是
ids[i] = (int)touch;
ids 是一个int数组,而 touch 是指针。
在64位构建中,指针是64位(与32位构建相反,它是32位),而int是32位,因此该分配在32位存储中存储64位值,这可能导致信息丢失
因此,编译器为
这样的行抛出错误是完全有效的ids[i] = touch;
但是,有问题的实际代码包含对int的显式c样式转换。这个显式的演员清楚地告诉编译器“闭嘴,我知道这段代码看起来不正确,但我知道我在做什么”。
所以编译器在这里非常挑剔,并且正确的解决方案使代码再次编译并仍然让它显示与Xcode 5.0完全相同的行为是首先强制转换为一个大小与a之一相匹配的整数类型指针,然后对我们实际想要的int进行第二次转换:
ids[i] = (int)(size_t)touch;
我在这里使用size_t,因为它总是与指针一样大小,无论平台如何。长时间不能用于32位系统而长时间不能用于64位Windows(而64位Unix和类似Unix的系统如OS X使用LP64数据模型,其中长64位,64位Windows使用LLP64数据模型,其中long的大小为32位(http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models))。
答案 1 :(得分:9)
将此ids[i] = (int)touch;
替换为ids[i] = (uintptr_t)touch;
它对我有用。
答案 2 :(得分:6)
我也遇到了这个问题。
ids[i] = (int)touch;
//此处发生错误=>我将此更改为以下内容。
ids[i] = (uintptr_t)touch;
然后我可以继续编译。也许你也可以尝试一下。
答案 3 :(得分:2)
你可以使用uintptr_t而不是int。它的标准是Xcode。
答案 4 :(得分:2)
XCode 5.1将所有架构更改为64位。
您可以在Build Settings
中更改以下所有内容的架构以支持32位编译希望它有所帮助。
答案 5 :(得分:0)
当然,解决方案是将id的类型从int更改为足以容纳指针的类型。
我不熟悉XCode,但解决方案应该如下:
将ids声明更改为:
intptr_t ids[IOS_MAX_TOUCHES_COUNT];
和产生错误的行:
ids[i] = (intptr_t)touch;
大多数"解决方案"当转换为较小的类型时,上面可能会丢失部分指针地址。如果该值再次被用作指针,那将证明是非常坏主意。
答案 6 :(得分:0)
您可以通过替换此行代码来修复此错误。
ids [i] =(uint64_t)touch;
您应该基于64位构建系统执行类型转换,因为“int”类型仅支持-32768~32768。
答案 7 :(得分:-1)
ids[i] = (int)touch; put * and check it.
ids[i] = *(int *)touch;