错误“从指针转换为较小类型'int'丢失信息”在将Xcode更新为5.1时的EAGLView.mm(5B130a) [英] Error "Cast from pointer to smaller type 'int' loses information" in EAGLView.mm when update Xcode to 5.1 (5B130a)

查看:408
本文介绍了错误“从指针转换为较小类型'int'丢失信息”在将Xcode更新为5.1时的EAGLView.mm(5B130a)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天,我将Xcode更新到最新版本(5.1(5B130a))以与 iOS 7.1 兼容。然后我构建我的项目,我得到错误从指针转换为较小类型'int'丢失信息 EAGLView.mm 文件(第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:从指针转换为较小类型'int'丢失信息

  //将触摸传递给超级视图
#pragma mark EAGLView - Touch Delegate
- (void)touchesBegan:(NSSet *)触及withEvent:(UIEvent *)事件
{
if(isKeyboardShown_)
{
[self handleTouchesAfterKeyboardShow];
返回;
}

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 *触摸触摸){
ids [i] =(int)touch; //错误发生在这里
xs [i] = [触摸locationInView:[触摸视图]]。x * view.contentScaleFactor ;;
ys [i] = [touch locationInView:[touch view]]。y * view.contentScaleFactor ;;
++ i;
}
cocos2d :: CCEGLView :: sharedOpenGLView() - > handleTouchesBegin(i,ids,xs,ys);
}


解决方案

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



原始代码是

  ids [i] =(int)touch; 

ids 是一组int和 touch 是一个指针。



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



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

  ids [i] =触摸; 

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



所以编译器是非常挑剔这里和正确的解决方案,使代码再次编译,仍然让它显示完全相同的行为,如在Xcode 5.0中首先强制转换为一个大小与指针匹配的整数类型然后再做一秒转换为我们实际想要的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位计算#64-bit_data_models ))。


Yesterday, I updated Xcode to the newest version (5.1 (5B130a)) to compatible with iOS 7.1. Then I build my project, I get the error "Cast from pointer to smaller type 'int' loses information" in EAGLView.mm file (line 408) when 64-bit simulators (e.g.: iPhone Retina 4-inch 64-bit) is selected.

I'm using cocos2d-x-2.2.2. Before I update Xcode, my project still can build and run normally with all devices.

Thanks for all recommendation.

Update: Today, i download the latest version of cocos2d-x (cocos2d-x 2.2.3). But the problem has still happened.

Here is some piece of code where that error occur:

/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);
}

解决方案

Apparently the clang version in Xcode 5.1 and above is more strict about potential 32bit vs. 64 bit incompatibilities in source code than older clang versions have been. To be honest, I think, clang is too restrictive here. A sane compiler may throw a warning on lines like this but by no way it should throw an error, because this code is NOT wrong, it is just potentially error-prone, but can be perfectly valid.

The original code is

ids[i] = (int)touch;

with ids being an array of ints and touch being a pointer.

In a 64bit build a pointer is 64bit (contrary to a 32bit build, where it is 32bit), while an int is 32bit, so this assignment stores a 64bit value in a 32bit storage, which may result in a loss of information.

Therefor it is perfectly valid for the compiler to throw an error for a line like

ids[i] = touch;

However the actual code in question contains an explicit c-style cast to int. This explicit cast clearly tells the compiler "Shut up, I know that this code does not look correct, but I do know what I am doing".

So the compiler is very picky here and the correct solution to make the code compile again and still let it show the exact same behavior like in Xcode 5.0 is to first cast to an integer type with a size that matches the one of a pointer and to then do a second cast to the int that we actually want:

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

I am using size_t here, because it is always having the same size as a pointer, no matter the platform. A long long would not work for 32bit systems and a long would not work for 64 bit Windows (while 64bit Unix and Unix-like systems like OS X use the LP64 data model, in which a long is 64bit, 64bit Windows uses the LLP64 data model, in which a long has a size of 32bit (http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)).

这篇关于错误“从指针转换为较小类型'int'丢失信息”在将Xcode更新为5.1时的EAGLView.mm(5B130a)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆