web-dev-qa-db-fra.com

Erreur "Cast du pointeur vers un type plus petit 'int' perd des informations" dans EAGLView.mm lors de la mise à jour de Xcode vers 5.1 (5B130a)

Hier, j'ai mis à jour Xcode vers la dernière version (5.1 (5B130a)) compatible avec iOS 7.1. Ensuite je construis mon projet, j'obtiens l'erreur "Cast from pointer to smaller type 'int' loses information" dans EAGLView.mm fichier (line 408) lorsque les simulateurs 64 bits (par exemple: iPhone Retina 4 pouces 64 bits) sont sélectionnés.

J'utilise cocos2d-x-2.2.2. Avant de mettre à jour Xcode, mon projet peut toujours être construit et exécuté normalement avec tous les appareils.

Merci pour toute recommandation.

Mise à jour: Aujourd'hui, je télécharge la dernière version de cocos2d-x (cocos2d-x 2.2.3). Mais le problème est toujours arrivé.

Voici un morceau de code où cette erreur se produit:

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

Apparemment, la version de clang dans Xcode 5.1 et supérieur est plus stricte sur les incompatibilités potentielles 32 bits contre 64 bits dans le code source que les anciennes versions de clang. Pour être honnête, je pense que le clang est trop restrictif ici. Un compilateur sensé peut lancer un avertissement sur des lignes comme celle-ci, mais il ne doit en aucun cas générer une erreur, car ce code n'est PAS faux, il est juste potentiellement sujet aux erreurs, mais peut être parfaitement valide.

Le code d'origine est

ids[i] = (int)touch;

avec ids étant un tableau d'ints et touch étant un pointeur.

Dans une version 64 bits, un pointeur est 64 bits (contrairement à une version 32 bits, où il est 32 bits), tandis qu'un int est 32 bits, donc cette affectation stocke une valeur 64 bits dans un stockage 32 bits, ce qui peut entraîner une perte d'informations.

Par conséquent, il est parfaitement valide pour le compilateur de lancer une erreur pour une ligne comme

ids[i] = touch;

Cependant, le code réel en question contient une conversion de style c explicite en int. Cette distribution explicite indique clairement au compilateur "Tais-toi, je sais que ce code ne semble pas correct, mais je sais ce que je fais".

Donc, le compilateur est très pointilleux ici et la bonne solution pour faire recompiler le code et le laisser montrer le même comportement exact comme dans Xcode 5.0 consiste d'abord à convertir en un type entier avec une taille qui correspond à celle d'un pointeur et à puis faites un deuxième casting à l'int que nous voulons réellement:

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

J'utilise size_t ici, car il a toujours la même taille qu'un pointeur, quelle que soit la plate-forme. Un long long ne fonctionnerait pas pour les systèmes 32 bits et un long ne fonctionnerait pas pour Windows 64 bits (alors que les systèmes Unix 64 bits et Unix comme OS X utilisent le modèle de données LP64, dans lequel un long est 64 bits, Windows 64 bits utilise les données LLP64 modèle, dans lequel un long a une taille de 32 bits ( http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models )).

37
Kaiserludi

Remplacez cette ids[i] = (int)touch; par ids[i] = (uintptr_t)touch;

Ça marche pour moi.

9
Mehul Mistri

Je rencontre aussi ce problème.

ids[i] = (int)touch; // une erreur se produit ici => je change cela en dessous.

ids[i] = (uintptr_t)touch;

Ensuite, je peux continuer à compiler. Vous pouvez peut-être essayer cela aussi.

6

XCode 5.1 change toute l'architecture en 64 bits.

vous pouvez simplement changer l'architecture pour prendre en charge la compilation 32 bits par tous ci-dessous dans dans les paramètres de construction

  • utilisez $ (ARCHS_STANDARD_32_BIT) dans Architecture au lieu de $ (ARCHS_STANDARD)
  • supprimer arm64 dans les architectures valides

J'espère que cela aide.

vous pouvez utiliser uintptr_t au lieu de int. son standard suivi de Xcode.

2
user3426385

Vous pouvez corriger cette erreur en remplaçant cette ligne de code.

ids [i] = (uint64_t) touch;

Vous devez effectuer une conversion de type basée sur un système de génération 64 bits car le type "int" ne prend en charge que -32768 ~ 32768.

0
user6385420

La solution est sûrement de changer le type d'ID de int en type suffisamment grand pour contenir un pointeur.

Je ne connais pas XCode, mais la solution devrait être quelque chose comme ceci:

Modifiez la déclaration des identifiants en:

intptr_t ids[IOS_MAX_TOUCHES_COUNT];

et la ligne produisant l'erreur pour:

ids[i] = (intptr_t)touch;

La plupart des "solutions" ci-dessus peuvent perdre une partie de l'adresse du pointeur lors de la conversion vers un type plus petit. Si la valeur est à nouveau utilisée comme pointeur, cela se révélera être une mauvaise idée extrêmement.

0
Rob G