IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Gérer le passage 32bits vers 64bits


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut Gérer le passage 32bits vers 64bits
    Je recompile des prgs en 64 bits sans trop de soucis fonctionnel, et en apparence sans erreur d'éxécution.
    Par contre, le nombre de warning est décourageant.

    J'utilise visual studio (sous Windows).
    unsigned et DWORD restent des 32 bits, et size_t (et SIZE_T) deviennent des 64 bits. Cas très fréquent de warning, des variables ou membres de structure de type unsigned auxquels on affecte des valeurs provenant de la STL (exemple, size() et length() qui sont des size_t).
    Une solution serait de user des static_cast<unsigned>, mais après en avoir tapé 328 je me dis qu'il y aura un soucis un jour... Sans compter la lisibilité du code.
    Une autre solution serait de remplacer tous les unsigned par des size_t. C'est facile et peut-être sécurisant, mais sans doute pas toujours opportun. Parfois aussi le warning est alors déplacé ailleurs.

    size_t ou unsigned ?
    Revoir tout le code, oui mais en faisant attention à quoi ?
    Y'a-t-il une "recette" ?
    Merci.

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Points : 725
    Points
    725
    Par défaut
    Salut,

    Tu as de la chance si l'appli que l'on te demande de porter ne caste pas des pointeurs vers des longs (et vice-versa). J'ai eu à intervenir sur une horreur de la sorte (qui en plus est multi-plateforme, donc les longs ne faisaient pas forcément la même taille partout).

    Pour ma part, je préfère utiliser size_t à unsigned ou à DWORD dans tout le code qui n'est pas spécifique à une plateforme. Size_t rajoute une valeur sémantique (on va stocker une taille ou un nombre d'élément) qu'il n'y a pas dans unsigned. Et size_t est justement fait pour s'adapter aux limites de l'architecture. À moins d'en stocker de gros tableaux, le surpoids lié à l'utilisation de size_t est négligeable.

    Pour le code spécifique plateforme (genre UI), un static_cast.
    "By and large I'm trying to minimize mentions of D in C++ contexts because it's as unfair as bringing a machine gun to a knife fight." - Andrei Alexandrescu

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Points : 2 627
    Points
    2 627
    Par défaut
    salut,

    les joies de la migration, à ce jeu j'ai découvert que le int faisait 4 octets quelque soit le plate-forme (tout le contraire de ce qu'on apprend à l'école).
    par contre le "long", 4 octets en 32bit et 8 octets 64bit.

    mieux vaut travailler avec les types de base.

  4. #4
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 045
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    long est malheureusement un type de base...
    J'évite de l'utiliser.
    Au niveau de visual studio, tu peux compiler un code 32 bits en activant les warnings qui sont liés à la compilation 64 bits en ajoutant l'option -Wp64 à la ligne de commande, c'est assez pratique.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Si la taille des données importe vraiment, je ne comprends pas que vous n'ayiez pas vos propres int32, int64, etc.
    Et là, la migration est triviale.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre averti
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Points : 306
    Points
    306
    Par défaut
    Pour assurer la portabilité, il est aussi possible d'utiliser les types d'entiers déclarés dans cstdint (C++11). Pour les entiers non signés, on y trouve, par exemple, uint32_t et uint64_t :
    http://www.cplusplus.com/reference/clibrary/cstdint/

  7. #7
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Points : 2 627
    Points
    2 627
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    long est malheureusement un type de base...
    J'évite de l'utiliser.
    Tout à fait d'accord.
    Quand tu utilises long tu sais à quoi t'attendre, par contre DWORD, je ne sais pas si c'est un int ou un long. (bon je viens de faire F12 dans VS, j'ai tout faux, c'est unsigned long)

    Y'a-t-il une "recette" ?
    Celle de Bousk me parait pas mal!

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    C++ ne donne pas la longueur des types de bases, seulement un rapport: char ≤ short ≤ int ≤ long ≤ long long
    un int est censé s'aligner sur la taille du mot mémoire.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    + 1, il y a aussi des plateformes (vieilles) sur lesquelles un int ne fait que 2 octets.

    Sinon pour revenir au souci initial, j'avoue que je ne comprends pas les réponses du style "utilise uint32, uint64", camboui explique que le problème vient justement des types de retour de fonction de la STL comme length() ou size() qui renvoie un size_t dont la taille varie en fonction du type de compilation !

    La seule solution est de faire du cast en masse ou de tout remplacer par size_t mais je comprends que ce soit vraiment dangereux et long dans une grosse appli...

    Sinon peut être désactiver ce warning précis ? C'est relativement rare en pratique les bugs dus à des erreurs de narrowing il me semble ?

    Edit : Peut être aussi, ne remplacer par size_t que dans les cas simples (par exemple si c'est pour un indice d'une boucle for) et garder des cast si c'est quelque chose de plus sensible (par exemple pour une donnée membre de classe)

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    C'est comme le dit Arzar, il a bien résumé.

    De la STL, des io (_read et _write), des variables locales pour gérer des boucles, des compteurs, etc. On mélange tout ça et ça fait plein de warning à cause des size_t et des unsigned qui s'adorent en 32 bits mais se déplaisent en 64 bits (sous Windows).

    J'ai entamé les corrections pour les cas les plus simples qui sont majoritaires, soit en remplaçant unsigned par size_t soit avec un cast. Dans le doute je laisse le warning.

    A propos de
    char ≤ short ≤ int ≤ long ≤ long long
    Ce fut une erreur AMA. Il aurait fallu imposer
    char < short < int < long
    long long n'aurait jamais dû exister...

    Merci pour vos avis !

  11. #11
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par camboui Voir le message
    char < short < int < long
    C'est pas gentil pour les architectures qui ne permettent pas d'accès mémoire sur des données de taille différentes (par exemple, un microcontrôleur)
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  12. #12
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Arzar Voir le message
    La seule solution est de faire du cast en masse ou de tout remplacer par size_t mais je comprends que ce soit vraiment dangereux et long dans une grosse appli...
    Non, la solution consiste à utiliser les bon types, pas à faire des cast.

    Citation Envoyé par Arzar Voir le message
    Sinon peut être désactiver ce warning précis ? C'est relativement rare en pratique les bugs dus à des erreurs de narrowing il me semble ?
    Pas tant que ça. J'en ai trouvé une dans un driver que j'utilise pas plus tard qu'il y a une semaine (une valeur 64 bits qui s'est retrouvée transformée en 32 bits ; mais comme on parlait de la taille en byte d'une flash, ce n'est pas passé inaperçu...). en fait c'était même pire que ça, puisque le bug ajoutait au narrowing un problème de signe (passage de unsigned long long en int, pour tout dire). Et 2 Go, en int, c'est assez surprenant
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  13. #13
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Non, la solution consiste à utiliser les bon types, pas à faire des cast.
    D'accord, mais comment gères-tu le cas où l'on a une struct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Toto
    {
       unsigned int nbMachin;
    };
    dont il faudrait remplacer par "le bon type"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct Toto
    {
       size_t nbMachin;
    }
    juste parce que quelque part quelqu'un a écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<Bidule> v;
    Toto t;
    t.nbMachin = v.size();
    Et que le passage en 64 bits entraîne un warning ?
    Perso dans ce genre de cas il me semble plus dangereux de remplacer par le bon type (size_t) sans savoir comment la struct est utilisée, plutôt que de faire un cast t.nbMachin = (unsigned)v.size();

  14. #14
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    C'est le genre de cas où je ne change rien, je laisse le warning. Heureusement c'est peu fréquent. L'adaptation du code peut-être posposée jusqu'à avoir une meilleur visibilité de la portée de la structure concernée.

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    En toute honnêteté, et pour autant, bien sur, que je sois sur qu'il n'y aura jamais autre chose que le résultat d'un appel à size(); je remplacerais volontiers l'unsigned int en size_t, sauf (hé oui, il y a toujours un cas "peau de banane" ) si mon application doit sauvegarder, pour une raison qui lui est propre, ce genre d'information en binaire

    En effet, si size_t peut etre considéré comme étant égal à unsigned int (typiquement, une valeur sur 4 bytes, du moins, sur de nombreuses architectures 32 bits), il y a de bonnes chances qu'il vaille 8 bytes sur les architecture 64 bits

    Vous aurez tout de suite compris que l'on aurait alors un soucis majeur de compatibilité entre le fichier écrit en 32 bits et l'application 64 bits (ou inversément) si l'on devait avoir un code proche de read(sizeof(size_t) * N);

    Mais, sinon, pour tous les cas finalement moins "border line", je ferais la modification autant que possible
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Normalement, il faudrait utiliser Container::size_type, en pratique j'utilise facilement size_t en attendant de pouvoir utiliser auto. A noter que l'hypothese qu'on arrive a avoir dans le futur plus de UINT_MAX elements dans un conteneur n'est pas reellement a exclure.

    Quant aux fichiers binaires, un fichier binaire n'est pas defini en fonction de type mais par un format et on devrait s'arranger normalement pour respecter ce format sans faire d’hypothèse sur le boutisme ou la taille des types (autre que le type est capable de contenir l'ensemble des valeurs prévues par le format bien sur).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #17
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Quant aux fichiers binaires, un fichier binaire n'est pas defini en fonction de type mais par un format et on devrait s'arranger normalement pour respecter ce format sans faire d’hypothèse sur le boutisme ou la taille des types (autre que le type est capable de contenir l'ensemble des valeurs prévues par le format bien sur).
    Mais c'est justement pour cela que le fait d'avoir recours à sizeof(size_t) si le fichier est susceptible d'avoir été écrit sous une architecture et d'être lu sous une autre.

    A ce moment là, le mieux est sans doute d'écrire la valeur sous un format qui "assure le minimum" (uint32_t) en "priant dieu" qu'il n'y ait jamais plus d'éléments que de valeurs représentables par ce type (ce qui empêcherait, de toutes manière, de lire le fichier sous une architecture 32 bits )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  18. #18
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais c'est justement pour cela que le fait d'avoir recours à sizeof(size_t) si le fichier est susceptible d'avoir été écrit sous une architecture et d'être lu sous une autre.

    A ce moment là, le mieux est sans doute d'écrire la valeur sous un format qui "assure le minimum" (uint32_t) en "priant dieu" qu'il n'y ait jamais plus d'éléments que de valeurs représentables par ce type (ce qui empêcherait, de toutes manière, de lire le fichier sous une architecture 32 bits )
    Utiliser sizeof() comme taille d'ecriture implique que le format est defini par la taille sur une architecture donnee et pas en lui-meme.

    Si on veut un format portable, on lit des bytes puis on reconstruit les valeurs en fonction de ceux-ci. (Il ne faudra alors repasser sur le code que si on porte sur une machine tellement bizarre qu'il faudra de toute facon se demander c'est quoi la portabilite d'un fichier binaire vers cette machine -- p.e. une ou les IO sont definies en mots de 36 bits tous significatifs et pas en octets).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  19. #19
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Utiliser sizeof() comme taille d'ecriture implique que le format est defini par la taille sur une architecture donnee et pas en lui-meme.

    Si on veut un format portable, on lit des bytes puis on reconstruit les valeurs en fonction de ceux-ci. (Il ne faudra alors repasser sur le code que si on porte sur une machine tellement bizarre qu'il faudra de toute facon se demander c'est quoi la portabilite d'un fichier binaire vers cette machine -- p.e. une ou les IO sont definies en mots de 36 bits tous significatifs et pas en octets).
    Ou une machine en middle endian...
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/02/2015, 11h14
  2. [AC-2013] Migration access 2010 32bits vers access 2013 64bits
    Par Gerard.chery dans le forum Access
    Réponses: 2
    Dernier message: 10/11/2014, 11h35
  3. printf() et migration de 32bits vers 64bits
    Par adiGuba dans le forum C
    Réponses: 2
    Dernier message: 13/09/2011, 17h08
  4. migration serveur 32Bit vers 64Bit
    Par brunon dans le forum Administration
    Réponses: 1
    Dernier message: 22/05/2008, 12h42
  5. [9207] Migration d'une base de 9207 32bits vers 64bits
    Par Cyborg289 dans le forum Oracle
    Réponses: 3
    Dernier message: 27/10/2006, 18h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo