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 :

Language permettant de gérer des structures de données "exotiques".


Sujet :

C++

  1. #1
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut Language permettant de gérer des structures de données "exotiques".
    Bonjour.

    Dans le cadre d'un projet perso consistant à lire un fichier de données d'un vieux jeux vidéo, j'ai été amené à développer une "nouvelle classe d'entier".

    Les contraintes étant de pouvoir déclarer des structures dont :
    - les données ne sont pas alignées,
    - les données peuvent être en little ou en big.
    Le code de lecture devant être fonctionnel sur toutes architectures.

    J'en suis arrivé au résultat en PJ. Je vous le soumet pour commentaires mais mes questions sont les suivantes :
    - Existait-t-il déjà des patterns pour réaliser cela (sous quel nom) ?
    - Y-a-t-il un langage prenant en compte ce genre de problématiques ?

    Je me suis aperçut que cela manquait aussi au boulot. Par exemple pour définir des trames (ne parlons même pas de la gestion des champs de bits).

    Merci de partager vos idées.

    Edit : à l'origine, j'avais posté ce message dans une rubrique "langages" en général. Je ne pense pas forcément à une solution c++, mais comme mon implémentation actuelle est en c++ et qu'elle est discutable, elle devrait avoir sa place ici.
    Fichiers attachés Fichiers attachés
    • Type de fichier : h Int.h (3,0 Ko, 76 affichages)

  2. #2
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut
    Je dirais que pas mal n'importe quel langage à typage dynamique de haut niveau va te permettre d'avoir des structures de données ad-hoc.

  3. #3
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par GnuVince Voir le message
    Je dirais que pas mal n'importe quel langage à typage dynamique de haut niveau va te permettre d'avoir des structures de données ad-hoc.
    pas tout à fait d'accord... tout dépend de la sureté de typage que l'on souhaite.


    j'aimerais bien des explications plus compréhensibles qu'une template c++ (que je n'ai pas envie de lire )

  4. #4
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Par exemple il faut lire un bloc dont la structure est la suivante (pour faire simple on a que des entiers) :
    offset 0, big endian, entier non signé sur 4 octets
    offset 32, little endian, entier non signé sur 2 octets
    offset 48, little endian, entier non signé sur 4 octets

    En c j'aurai tendance à déclarer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct 
    {
      unsigned int a;
      unsigned short b;
      unsigned int c;
    }
    Mais le problème est que c'est faux :
    (1) Si je ne suis pas sur du 32 bits
    (2) Si le compilo ne tasse pas la structure
    (3) Dans tous les cas à cause de l'endianess

    Les solutions sont donc :
    (1) Utiliser uint16_t, et uint32_t (ça c'est pas trop dégueulasse c'est du C99 il me semble).
    (2) Utiliser l'attribut "packing" ou je ne sais plus quoi (ça c'est pas portable d'un compilo à l'autre, sous MSVC++ je crois que ce sont des pragmas... bref).
    (3) Faire une fonction/macro que l'on appelle swap, ou mieux read/write_little/big. Là ça va faire du code illisible à la fin.


    Dans l'implémentation que je propose on déclare :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct 
    {
      be_uint32_t a;
      le_uint16_t b;
      le_uint32_t c;
    } foo;
    La structure sera bonne partout. Comme c'est du c++ quand on accedera aux champs la conversion d'endianess se fera automatiquement.

    Je me demandais si il n'y avait pas moyen d'optimiser ce que j'avais fait en l'intégrant au langage. Les compilos pourraient générer le code d'accès au champ et ce serait utilisable même en c.

    Voila

  5. #5
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Je me permet de remonter le sujet, j'aimerais vraiment avoir vos retours.

  6. #6
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    - Le compilateur n'est pas du tout obligé d'éliminer les portions mortes de code, ce qui peut être gênant puisque tout est inline. La façon portable de le faire est de faire des spécialisations partielles.
    - très dommage de ne pas court-circuiter l'opérator T lorsque l'architecture d'exécution correspond à celle des données. Avec spécialisation partielle, on pourrait en effet ne souffrir aucune pénalité par rapport à du code natif quand elles coïncident.
    - pourquoi _x est-il public?
    - sur le principe, est-il rigoureusement nécessaire d'arranger en mémoire les octets comme ils figurent sur le fichier? Pourquoi ne pas tout simplement gérer les E/S classiquement, et utiliser les types de taille garantie (uint16_t...) pour le compactage? Pour les structures composées, toutes les librairies de serialisation que je connais (Eternity, Boost.Serialization, MFC et autres), imposent de toute façon un archivage membre à membre, je ne vois donc pas l'intérêt de répliquer en mémoire la disposition sur fichier.

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Pourquoi chercher à dupliquer le format du fichier en mémoire ? Un format de fichier c'est une chose, une structure de donnée c'est autre chose, les contraintes sont souvent différentes.

    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
    19
    20
    21
    22
    23
    24
    25
    26
    unsigned long readUInt32BE(std::istream& src)
    {
      unsigned long result = static_cast<unsigned long>(src.get());
      result = (result << 8) | static_cast<unsigned long>(src.get());
      result = (result << 8) | static_cast<unsigned long>(src.get());
      result = (result << 8) | static_cast<unsigned long>(src.get());
      return result;
    }
     
    unsigned readUInt16BE(std::istream& src)
    {
      unsigned long result = static_cast<unsigned long>(src.get());
      result = (result << 8) | static_cast<unsigned long>(src.get());
      return result;
    }
     
    struct
    {
      unsigned long a;
      unsigned b;
      unsigned long c;
    } s;
     
    s.a = readUInt32BE(src);
    s.b = readUInt16BE(src);
    s.c = readUInt32BE(src);
    Code 100% portable et sans utiliser de #pragma et autre typedef.

  8. #8
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Merci pour vos remarques.

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Mais pourquoi défiez-vous tous la norme en plaçant ce bête underscore devant vos noms de variables plutôt qu'à la fin par exemple ?

    Un jour ça va péter...

  10. #10
    Membre confirmé

    Inscrit en
    Octobre 2007
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 234
    Points : 644
    Points
    644
    Par défaut
    Un nom (de variable ou autre) doit commencer par une lettre, le underscore étant considéré comme une lettre, ça ne pose pas de problèmes.

  11. #11
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Comme l'ont clairement expliqué les auteurs de "Standard de Programmation en C++", il est fortement déconseillé de préfixer par "_" les noms de variables. Parce qu'elles pourraient bien être réservées à la bibliothèque standard...

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    Citation Envoyé par kinji1 Voir le message
    Un nom (de variable ou autre) doit commencer par une lettre, le underscore étant considéré comme une lettre, ça ne pose pas de problèmes.
    mais il y a la suite:

    "Names starting with underscore are reserved for special facilities in the implementation and the run-time environment, so such names should not be used in application programs"

    Stroustrup 4.9.3

  13. #13
    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
    Pour la question initiale: Ada a des clauses de representation permettant une partie de ce que tu veux, mais vraisemblablement pas tout (en particulier la gestion de la boutitude n'est pas presente).

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Je ne connais pas l'ensemble des identificateurs réservés en C++, mais il doit être voisin de celui du C, non ?

Discussions similaires

  1. Présentation des structures de données arborescentes
    Par PRomu@ld dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 30/01/2009, 14h39
  2. Réponses: 2
    Dernier message: 15/01/2009, 18h45
  3. Files Mapping pour stocker des structures de données
    Par Targan dans le forum Débuter
    Réponses: 0
    Dernier message: 27/12/2007, 11h38
  4. redim Imbrication des structures de données
    Par totoche dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 28/11/2007, 15h23
  5. combobox et me permette le choix des bases de données
    Par crash override dans le forum Composants VCL
    Réponses: 6
    Dernier message: 21/10/2005, 16h28

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