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 :

Détection de l'endianess


Sujet :

C

  1. #1
    Membre habitué Avatar de Kromagg
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2008
    Messages : 275
    Points : 198
    Points
    198
    Par défaut Détection de l'endianess
    Bonjour à tous

    En parcourant le code du moteur OpenSceneGraph, je suis tombé sur la fonction permettant de détecter l'endianness de la machine, en voici une version légèrement modifiée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    const char* getCpuByteOrder()
    {
        union 
        {
            char big_endian_1[2];
            short is_it_really_1;
        } u;
        u.big_endian_1[0] = 0;
        u.big_endian_1[1] = 1;
     
        printf("%i\n", u.is_it_really_1);
     
        if (u.is_it_really_1 == 1)
            return "bigEngian";
        else 
            return "littleEndian";
    }
    Sur ma machine u.is_it_really_1 vaut 256 alors qu'il n'a pas été initialisé. Je ne vois pas non plus l'intérêt d'utiliser big_endian_1 (de plus c'est un tableau).
    Comment fonctionne cette fonction ? Le type des variables est-il important ? Pourquoi utiliser une union ?

    Kromagg
    C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus)

  2. #2
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Le char vaut 1 octet, et le short vaut 2 octets.
    Le fait d'utiliser l'union fait que modifier la valeur de big_endian_1 modifiera aussi la valeur de is_it_really_1 car ils utiliseront le même espace mémoire.

    Du coup si on fait comme ton code en mémoire on aura ça :

    00000000 00000001 -> Big endian
    00000001 00000000 -> Little endian

    Donc si on utilise un short, comme il utilise la même partie de mémoire, on aura 1 en big endian et 256 en little endian.
    Plus tu pédales moins fort, moins t'avances plus vite.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Kromagg Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    const char* getCpuByteOrder()
    {
        union 
        {
            char big_endian_1[2];
            short is_it_really_1;
        } u;
        u.big_endian_1[0] = 0;
        u.big_endian_1[1] = 1;
     
        printf("%i\n", u.is_it_really_1);
     
        if (u.is_it_really_1 == 1)
            return "bigEngian";
        else 
            return "littleEndian";
    }
    Bizarre. Moi j'aurais plutôt affecté 1 dans u.is_it_really_1 puis serais allé tester big_endian_1[1]. Une seule affectation au lieu de 2...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre habitué Avatar de Kromagg
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2008
    Messages : 275
    Points : 198
    Points
    198
    Par défaut
    Merci Pouet_forever, c'est beaucoup plus clair

    Mais est-ce portable comme solution, est-ce que les types char et short sont codés sur le même nombre d'octets quelque soit l'OS, oy est-ce que cela dépend entièrement de l'architecture matériel ?

    Kromagg
    C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus)

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Par définition, char est codé sur un byte. On n'a pas de garantie sur la taille d'un short.
    Mais on peut en tenir compte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const char* getCpuByteOrder()
    {
        union
        {
            char big_endian_1[sizeof (short)];
            short is_it_really_1;
        } u;
        u.is_it_really_1 = 1;
        return u.big_endian_1[0]==1 ? "littleEndian" : "bigEngian";
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Kromagg Voir le message
    Mais est-ce portable comme solution, est-ce que les types char et short sont codés sur le même nombre d'octets quelque soit l'OS, oy est-ce que cela dépend entièrement de l'architecture matériel ?
    Non ce n'est pas garantie être portable :
    • A cause de la taille variable des types d'une plateforme à l'autre (point que le code fourni par diogene résous)
    • Car vu de la norme, dans une union, seule la lecture du dernier élément écrit est correct [1] (en clair après avoir écris is_it_really_1 la norme ne garantie pas que tu puisse lire big_endian_1).


    En pratique, sur les plateformes courantes (et moyennant la correction de diogene) tu ne devrais pas rencontrer de problème particulier.



    [1] Je laisse volontairement ici les cas particuliers qui ne nous concerne pas.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    À votre place, j'utiliserais le type entier le plus grand possible (genre long ou long long), de peur de tomber sur une implémentation où sizeof(char)==sizeof(short) mais où les autres types entiers seraient plus grands.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    À votre place, j'utiliserais le type entier le plus grand possible (genre long ou long long), de peur de tomber sur une implémentation où sizeof(char)==sizeof(short) mais où les autres types entiers seraient plus grands.
    J'ai une fois travaillé sur un ordinateur Siemens/Nixdorf sur lequel le short valait 2, le int valait 4 et le long 6. Au début mes codes ne marchaient pas bien et je galérais. Rhaa la tronche que j'ai faite quand j'ai découvert cte merde !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre habitué Avatar de Kromagg
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2008
    Messages : 275
    Points : 198
    Points
    198
    Par défaut
    Dans ce cas y a-t-il un moyen correcte de détecter l'endianness d'une architecture ?

    Kromagg
    C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus)

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Comme je te dis: Le type le plus petit contre le type le plus grand.

    Si les deux sont de taille égale, alors tu n'auras pas de problèmes d'endianness de toute façon.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par diogene Voir le message
    Par définition, char est codé sur un byte. On n'a pas de garantie sur la taille d'un short.
    Mais on peut en tenir compte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const char* getCpuByteOrder()
    {
        union
        {
            char big_endian_1[sizeof (short)];
            short is_it_really_1;
        } u;
        u.is_it_really_1 = 1;
        return u.big_endian_1[0]==1 ? "littleEndian" : "bigEngian";
    }
    Le problème de cette méthode et tu le sais diogene, c'est qu'elle invoque un comportement indéterminé.
    On peut contourner le problème (6.3.2.2.7) ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    const char * getCpuByteOrder(void)
    {
       short is_it_really_1 = 1;
       return *(unsigned char*)&is_it_really_1 == 1U ? "littleEndian" : "bigEngian";
    }
    L'ennui c'est qu'on ne détecte pas les endianness exotique stype middle endian (PDP-11).
    Cordialement.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

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

Discussions similaires

  1. [debugger] détection écriture mémoire
    Par tut dans le forum MFC
    Réponses: 3
    Dernier message: 07/01/2004, 10h17
  2. détection de player
    Par mat10000 dans le forum Flash
    Réponses: 8
    Dernier message: 23/10/2003, 16h36
  3. Détection MySql
    Par gjullien dans le forum Bases de données
    Réponses: 5
    Dernier message: 20/08/2003, 18h15
  4. Détections avec WebBrowser
    Par Wazo_Sportive dans le forum Composants VCL
    Réponses: 4
    Dernier message: 11/08/2002, 19h32
  5. Détection de 2 touches appuyées
    Par cyrose dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/07/2002, 16h25

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