Error "Cast from pointer to smaller type 'int' loses information" in EAGLView.mm when update Xcode to 5.1 (5B130a)

41,061

Solution 1

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.

Therefore 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)).

Solution 2

I meet this problem too.

ids[i] = (int)touch; // error occur here => I change this to below.

ids[i] = (uintptr_t)touch;

Then i can continue compiling. Maybe you can try this too.

Solution 3

XCode 5.1 is change all architecture to 64 bit.

you can just change architecture to support 32 bit compilation by all below in in Build Settings

  • use $(ARCHS_STANDARD_32_BIT) at Architecture instead of $(ARCHS_STANDARD)
  • remove arm64 at Valid Architectures

Hope it helps.

Solution 4

You can fix this error by replacing this line of code.

ids[i] = (uint64_t)touch;

You should perform type conversion based on 64bit build system because the type "int" supports only -32768 ~ 32768.

Share:
41,061

Related videos on Youtube

nvg58
Author by

nvg58

Updated on July 09, 2022

Comments

  • nvg58
    nvg58 almost 2 years

    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);
    }
    
    • Johnny Mopp
      Johnny Mopp over 10 years
      If pointers are 64 bits and ints are 32 bits, an int is too small to hold a pointer value.
    • nvg58
      nvg58 over 10 years
      Thanks. But I don't want to edit code in "EAGLView.mm" because it's a "library file". Anw, the project still build and run normally when i use Xcode 5.0 with iOS 7.0. The problem just occur with Xcode 5.1
    • LearnCocos2D
      LearnCocos2D over 10 years
      The problem was there before, you just are being notified of it. whether it was an actual problem is a different matter though.
    • nvg58
      nvg58 over 10 years
      @LearnCocos2D: so, how can i "overcome" the error without editing any not-my-code or in-library-file lines?
    • LearnCocos2D
      LearnCocos2D over 10 years
      If it's anything like cocos2d-iphone v2.x and just based on this slice of code in a core class I wager it's safe to say that cocos2d-x 2.x also is not compatible with 64 bit code, and you can expect all kinds of issues (not just compile-time but also runtime). There's probably little you can do except look or hope for a fixed 2.x version or upgrade to 3.x (I would assume it's 64-bit safe but this is just a guess, do research this issue before you upgrade). The only alternative is really to take time and fix all 64-bit code issues, of which there may be some non-trivial issues.
    • nvg58
      nvg58 over 10 years
      Actually, I tried to build and run my project with cocos2d-x 2.2.3 but the problem is still there. Let me try with 3.x version and report if it works.
    • Muhammad Shauket
      Muhammad Shauket over 9 years
      use this line of code ids[i] = (int)(size_t)touch; instead of ids[i] = (int)touch
  • nvg58
    nvg58 over 10 years
    Did i have to face to unexpected runtime issues
  • Peeradon Tadsanaborrisut
    Peeradon Tadsanaborrisut over 10 years
    i guess not, i've found another discussion on this - http://stackoverflow.com/questions/18913906/xcode-5-and-ios-‌​7-architecture-and-v‌​alid-architectures .or at least, i think cocos2d-x-3.0rc0 has fixed this issue already.
  • Kaiserludi
    Kaiserludi over 9 years
    You are correct, but cocos actually only uses that address as a unique id. Changing the type of ids would be the cleanest solution, but I decided against it when being confronted with this issue myself, as it only introduced a lot of issues with other code that is relying on ids being an int-array. Just re-enforcing the old behavior of Xcode 5.0 and earlier versions, that already cut away parts of the address by casting it to int, won't introduce any new bugs and avoids the need to learn and understand lots of implementation-internal cocos code.
  • Rafael Ruiz Muñoz
    Rafael Ruiz Muñoz over 9 years
    Casting (int)(size_t)boo instead (int)boo solved my problem. Thanks!
  • Kaiserludi
    Kaiserludi over 8 years
    This answer is incorrect for the reasons that have already been mentioned in the comment of stackoverflow.com/a/22474752/404734.
  • nafsaka
    nafsaka about 8 years
    It solved my problem too. I wish that you write those answer first than the explanation.
  • Kaiserludi
    Kaiserludi over 5 years
    "because the type "int" supports only -32768 ~ 32768" This is not true for any modern desktop or mobile OS or any OS that is targeted by cocos2d-x. On all of them int is 32bit, not 16bit.