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 :

Comparaison de structures : méthode miracle ?


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut Comparaison de structures : méthode miracle ?
    Bonjour,

    J'ai des structures à comparer.
    Pour comparer une structure, on est donc normalement obligé de créer une fonction qui compare chaque champs un à un pour éviter les problèmes de padding :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    BOOL compareMyStruct(MY_STRUCT * struct1, MY_STRUCT * struct2){
    	if(
    		(struct1->elm1 != struct2->elm1) ||
    		(struct1->elm2 != struct2->elm2) ||
    		// ..
    		(struct1->elmX != struct2->elmX)	
    	){
    		return FALSE;
    	}
     
    	return TRUE;
    }
    Y a t-il une petite astuce pour que si j'ajoute un membre dans la structure, qu'il y ai une erreur/warning à la compilation si j'oublie de modifier la fonction compareMyStruct() en conséquence ?

    => Je cherche une méthode fiable pour éviter tout oubli

    Merci d'avance

  2. #2
    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
    Non.

    Mais si la déclaration de la fonction est à coté de la définition de la structure, une paire de commentaire bien placés devraient aider.

    C'est la première étape de "documenter et spécifier".
    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

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Le problème des commentaires, c'est que quand tu dois rendres un projet rapidement et que l'on te met la pression, tu as vite fait de ne pas lire les commentaires alors qu'avec un bon gros #error, ça c'est imparable... mais bon s'il n'y a pas le choix, allons y pour les commentaires

    merci

  4. #4
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    Pourquoi un memcmp ne marcherais pas?

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Voe,
    Citation Envoyé par boboss123 Voir le message
    Le problème des commentaires, c'est que quand tu dois rendres un projet rapidement et que l'on te met la pression, tu as vite fait de ne pas lire les commentaires alors qu'avec un bon gros #error, ça c'est imparable... mais bon s'il n'y a pas le choix, allons y pour les commentaires

    merci
    Faut pas pousser, quelques mots bien placés, en plus sur un programme que tu développes !!
    Si les cons volaient, il ferait nuit à midi.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par mith06 Voir le message
    Pourquoi un memcmp ne marcherais pas?
    Le compilateur peut ajouter des octets de padding et je pense (à vérifier) que ces octets ont une valeur indéterminé.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par mith06 Voir le message
    Pourquoi un memcmp ne marcherais pas?
    Ce que j'ai remarqué dans la déclaration d'une structure (je ne sais pas si c'est vrai dans tous les cas) :
    1- les variables sont placées dans l'ordre de leur déclaration.
    2- les variables sont placées à des adresses qui sont divisibles par la taille de la variable.
    3- la taille totale de la structure est divisible par la taille de la plus grosse variable

    Ex
    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
     
    typedef struct {
        UINT8 val8bits;
        UINT32 val32bits;
        UINT16 val16bits;
        UINT8 val8bits_2;
    } MY_STRUCT;
     
    void main(void){
        MY_STRUCT myStruct;
     
        myStruct.val8bits = 1;
        myStruct.val32bits = 2;
        myStruct.val16bits = 3;
        myStruct.val8bits_2 = 4;
     
        printf("sizeof(myStruct) = %i\r\n", sizeof(myStruct));
        printf("offset @myStruct.val8bits = 0\r\n");
        printf("offset @myStruct.val32bits = %i\r\n", (unsigned int)&myStruct.val32bits - (unsigned int)&myStruct.val8bits);
        printf("offset @myStruct.val16bits = %i\r\n", (unsigned int)&myStruct.val16bits - (unsigned int)&myStruct.val8bits);
        printf("offset @myStruct.val8bits_2 = %i\r\n", (unsigned int)&myStruct.val8bits_2 - (unsigned int)&myStruct.val8bits);
    }
    Si myStruct.val8bits est à l'adresse 0, myStruct.val32bits sera donc à l'adresse 4 (4 correspond à 8 octets = 32bits), myStruct.val16bits à l'adresse 8 et myStruct.val8bits_2 à l'adresse 10.
    Il y a 3 octets de padding entre myStruct.val8bits et myStruct.val32bits et 1 octets de padding après myStruct.val8bits_2.
    => la taille de la structure sera donc de 12 octets

    Lorsqu'une variable est déclarée en locale comme dans le cas cité précédemment (variable temporaire), elle est mise sur la pile et les champs ne sont pas initialisés à la déclaration de la variable. Les valeurs des octets de padding dépendent donc des valeurs des anciennes variables qui était précédemment au même endroit dans la pile.
    Par contre les variables qui sont déclarées en extern/static (variables permanentes) ont tous leur octets qui sont initialisés à 0 au lancement du programme : je suppose donc qu'un memcmp sur deux structures en static doit fonctionner (à condition de ne pas avoir fait un memcpy avec une structure non static/extern pour modifier les valeurs de ces structures).


    Si on change l'ordre des variables de la structure comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
        UINT8 val8bits;
        UINT8 val8bits_2;
        UINT16 val16bits;
        UINT32 val32bits;
    } MY_STRUCT;
    => la taille de la structure sera de 8 octets et il n'y aura pas d'octets de padding

    Attention : comme je l'ai dit précédemment, je ne suis pas sure que ça soit vrai dans tous les cas (je ne connais pas bien la norme du C).

  8. #8
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Le compilateur peut ajouter des octets de padding et je pense (à vérifier) que ces octets ont une valeur indéterminé.
    On doit pouvoir empécher cela avec les indications pour le compilateur lié au packing des structures.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    On doit pouvoir empécher cela avec les indications pour le compilateur lié au packing des structures.
    => mais ce n'est pas portable me semble t-il car les commandes utilisées dépendent du compilateur et je ne suis pas sure que ça supprime le padding en fin de structure...

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    J'osais croire que c'était des trucs portables.
    Sinon, même si votre structure possède du padding, elle devrait être comparable (avec memcpy), car la structure n'est définie qu'une fois.
    Je veux dire par là que si on une déclaration comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct MyStruct
    {
       char x;
       int y;
    };
    Faire un memcmp de deux instance de MyStruct est possible, car les deux instances auront le même padding.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    Futur Membre du Club
    Homme Profil pro
    CHercheur
    Inscrit en
    Août 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : CHercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 12
    Points : 9
    Points
    9
    Par défaut astuce
    J'ajouterais une variable qui correspond au nombre d'éléments de la structure.
    Et dans ma comparaison, mettrais en dur une comparaison de cette variable avec le nombre définit dans la sructure.
    C'est pas super, mais bon...

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    #include <iostream>
     
    using namespace std;
     
    struct MS {
            size_t y = 1;  // Doit correspondre aux nombres d'éléments ci-dessous (ici un seul  int a)
            int a;
     
    } ;
     
    bool compareMyStruct(MS struct1, MS struct2){
        if( struct1.y != 1 ) { cerr << "WARN : STRUCT COMPARE TO BE MODIFIED" << endl; } // A modifier a chaque ajout, PB : erreur a l'execution et non compilation
    	if(
    		(struct1.a != struct2.a)
    	){
    		return false;
    	}
     
    	return true;
    }
     
    int main()
    {
     
     
        MS A;
        MS B;
        A.a = 2;
        B.a = 3;
        cout << " A=B ? " << compareMyStruct(A,B) << endl;
        cout << A.a << endl;
        cout << "Hello world!" << endl;
        return 0;
    }

  12. #12
    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
    On ne peut écrire cela en C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct MS {
            size_t y = 1;  // Doit correspondre aux nombres d'éléments ci-dessous (ici un seul  int a)
            int a;
     
    } ;
    L'inconvénient de mettre une valeur sentinelle dans la structure est qu'il faut explicitement et correctement initialiser toutes les instances de struct MS qui seront créées.

    Personnellement, je mettrais deux gardes-fou, le premier à coté de la définition de la structure qui sera actualisé à chaque modification de la structure indiquant, pour reprendre l'idée de boutor, le nombre de champs et le second dans la fonction de comparaison indiquant le nombre de champs comparés qui sera actualisé à chaque modification de la fonction. Par exemple :
    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
    #define NBCHAMPS_MY_STRUCT 10
    typedef struct  {
       ... elm1;
    ...
       ... elm10;
    }MY_STRUCT ;
    ....
    BOOL compareMyStruct(MY_STRUCT * struct1, MY_STRUCT * struct2){
    #define NBCHAMPSCOMP_MY_STRUCT 10
     if( NBCHAMPSCOMP_MY_STRUCT != NBCHAMPS_MY_STRUCT) ... // erreur
     return   (struct1->elm1 == struct2->elm1) &&
              (struct1->elm2 == struct2->elm2) &&
              // ...
              (struct1->elm10 == struct2->elm10);
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  13. #13
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    La méthode miracle que tu cherches c'est memcmp. Padding ou pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    BOOL compareMyStruct(MY_STRUCT * struct1, MY_STRUCT * struct2)
    {
        return memcmp(struct1,struct2,sizeof(MY_STRUCT)) == 0;
    }

  14. #14
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    mais dans ce cas faut peu être penser à bien l'initialiser avec bzero histoire de pas avoir de la merde dans la mémoire

    Ont sais jamais un char[300] avec juste un mot de 10 caractères y a quoi après ^^.

  15. #15
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 429
    Points
    1 429
    Par défaut
    Ont sais jamais un char[300] avec juste un mot de 10 caractères y a quoi après ^^.
    Effectivement dans ce cas là il faut considéré que que les octets qui suivent sont aléatoires.

    Donc d'un point de vu utilisateur deux structures peuvent être considéré "égales", avec cependant une représentation en mémoire différente (octet après '\0' non significatifs).

    L'ordinateur ne peut pas ce placer dans ce point de vue. memcmp n' est donc pas une solution viable ( dans ce cas là).

    Je ne connais pas de méthode en C qui permette de comparer c'est deux structures sans ce frapper les champs à la main, et prendre ainsi le risque de rendre la méthode de comparaison obsolète à chaque fois que l'on modifie la déclaration de la structure.

  16. #16
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    d'ou la fonction bzero histoire de mettre tout tes bits à zéro.

    correction : Les pointeurs n'ont pas forcement le même adressage mais la même valeurs.

    La seule solution miracle c'est la rigueur dans ce cas.

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    mettre à zéro la structure à l'initialisation n'est pas une solution car si tu crée une librairie, tu ne sais pas forcemetn comment l'utilisateur de la lib va manipuler tes variables après.

    Voici quelques exemple qui peuvent générer des erreurs :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct {
        char val1;
        int val2;
        char str[9];
    } MY_STRUCT;
     
    //#define INITILIZE_STRUCT_TO_ZERO
    //#define TEST1 // première methode (si NITILIZE_STRUCT_TO_ZERO non defini, les structures ne sont pas identiques)
    //#define TEST2 // seconde methode (les structures sont identiques)
    #define TEST3 // troisieme methode (les structures ne sont pas identiques)
     
    void modifyStruct(MY_STRUCT * ptStruct){
     
    #ifdef TEST1
        MY_STRUCT structTmp;
     
        #ifdef INITILIZE_STRUCT_TO_ZERO
        memset(&structTmp, 0, sizeof(structTmp));
        #endif
     
        structTmp.val1 = 1;
        structTmp.val2 = 2;
     
        memcpy(ptStruct, &structTmp, sizeof(structTmp));
    #endif
     
    #ifdef TEST2
        ptStruct->val1 = 1;
        ptStruct->val2 = 2;
    #endif
    }
     
     
    int main(){
        MY_STRUCT myStruct1;
        MY_STRUCT myStruct2;
     
        memset(&myStruct1, 0, sizeof(myStruct1));
        memset(&myStruct2, 0, sizeof(myStruct2));
     
        #ifdef TEST3
            strcpy(myStruct2.str, "salut !");
     
            strcpy(myStruct1.str, "hello world !"); // genere une erreur de comparaison
            strcpy(myStruct1.str, "salut !");
     
        #else
            modifyStruct(&myStruct1);
     
            myStruct2.val1 = 1;
            myStruct2.val2 = 2;
        #endif
     
     
        if(memcmp(&myStruct1, &myStruct2, sizeof(myStruct1)) == 0){
            printf("Structures identiques\n");
        } else {
             printf("Structures non identiques\n");
        }
     
     
        return 0;
    }

  18. #18
    Membre confirmé Avatar de saad.hessane
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2008
    Messages : 315
    Points : 496
    Points
    496
    Par défaut
    D'où l'intérêt de masquer l'implémentation, et de fournir les fonctions de manipulations de la structure.
    Fichier "public.h"
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifndef PUBLIC_H_INCLUDED
    #define PUBLIC_H_INCLUDED
    typedef struct maStruct maStruct; //Déclaration d'un type incomplet
     
    //Les fonctions autorisés
    maStruct *maStructInit();
    void maStructFree(maStruct *);
    int maStructCmp(maStruct const *, maStruct const *);
    #endif
    Fichier "private.h"
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifndef PRIVATE_H_INCLUDED
    #define PRIVATE_H_INCLUDED
     
    //Déclaration du type complet
    struct maStruct{
      char val1;
      int val2;
      char str[9];
    };
    #endif
    Fichier "implementation.c"
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include "public.h"
    #include "private.h"
     
    maStruct *maStructInit()
    {/*...*/}
    void maStructFree(maStruct *s)
    {/*...*/}
    int maStructCmp(maStruct const *s1, maStruct const *s2)
    {/*...*/}
    Tu fournis au client la librairie compilée, et le fichier "public.h".
    L'intérêt réside aussi dans le fait que le jours où tu veux ajouter/supprimer/renommer un champ, l'utilisateur n'a pas à modifier son code.
    Par contre l'utilisateur ne peut "manipuler" qu'un pointeur sur ta structure (Je vois cela comme un avantage !).
    Pour la comparaison en elle même je dirais ça dépend. Si ta structure contient des pointeurs, faudra les déréférencer et comparer un à un (à part si deux structures sont égales si elles pointent vers la même zone mémoire, c'est toi qui définit la règle d'égalité).
    Si la structure contient des valeurs, un memcmp suffit (calloc dans l'initialisation).

  19. #19
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Memcmp n'est pas la solution, c'est clair, c'est net, c'est évident. Sauf à initialiser tout le padding à 0 et si les structures ne sont jamais modifiées par la suite et ça, c'est relativement peu probable. Je ne pense pas qu'on puisse garantir qu'en modifiant un champ, les bits de padding restent à 0.

    Les instructions pour faire des structures compactes (avec packed quelque chose) dépendent du compilateur, car la norme ne possède pas si j'ai bonne mémoire d'indication à ce sujet.

    Ce que j'ai remarqué dans la déclaration d'une structure (je ne sais pas si c'est vrai dans tous les cas) :
    1- les variables sont placées dans l'ordre de leur déclaration.
    2- les variables sont placées à des adresses qui sont divisibles par la taille de la variable.
    3- la taille totale de la structure est divisible par la taille de la plus grosse variable
    J'ai un article en cours de rédaction sur le sujet, qui traine d'ailleurs mais je n'ai ni le temps ni la motivation de le finir. On peut faire pas mal de remarques de ce genre. On s'aperçoit aussi en changeant de plateforme qu'on faire des remarques totalement autres / supplémentaires / qui ne paraissent pas en accord au premier abord. D'après la norme, il y a 2 choses dont tu peux être sûr : les champs sont dans l'ordre de déclaration du type, le premier champ est à la même adresse que la structure.


    Ont sais jamais un char[300] avec juste un mot de 10 caractères y a quoi après ^^.
    Et si après tu mets un mot de taille 5 ? Que deviennent les anciens caractères non mis à zéro au début ? ^^

    La seule vraie méthode de comparer deux méthodes, c'est champ par champ (surtout quand on rajoute des problèmes pour comparer des champs qui sont des chaines, vous l'avez bien dit).

    Le PO pose une question qui ne peut pas avoir de réponse "standard" : ce n'est pas un problème sémantique mais de logique. Une bonne solution est celle de diogene (pour changer ^^). Tu peux aussi faire des comparaisons avec des commandes du pré-processeur et mettre un #error pour avoir une erreur à la compilation.

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Bon je pense qu'on peut dire que le sujet est clos : merci pour votre participation
    => pour moi :memcmp peut être utilisé en prenant pas mal de précautions : donc trop risqué, mieux vaut comparer champs par champs

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Comparaison de structures avec tableau ?
    Par Nikolas dans le forum C++
    Réponses: 26
    Dernier message: 01/11/2010, 17h06
  2. comparaison de structures
    Par Monstros Velu dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 13/06/2008, 13h51
  3. [BDS2006Win32] Comparaison de structure record
    Par edrin17 dans le forum Débuter
    Réponses: 6
    Dernier message: 24/08/2007, 19h09
  4. Comparaison sur structure
    Par HaTnuX dans le forum C
    Réponses: 4
    Dernier message: 05/12/2006, 13h48
  5. Comparaison de structure de deux tables
    Par Ryan Sheckler dans le forum Outils
    Réponses: 7
    Dernier message: 15/02/2006, 22h00

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