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 :

Probleme de comprehension de macros


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 21
    Points : 23
    Points
    23
    Par défaut Probleme de comprehension de macros
    Bonjour,

    Me remettant au gout du jour a propos du langage C, je decouvre avec plus d'enthousiasme les joies des macros en C. A vrai dire, devant adapter banc de test de quelqu'un, je me trouve devant ceci :

    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 container_of(ptr, type, member) ({                      \
            const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
            (type *)( (char *)__mptr - offsetof(type,member) );})
     
    #define list_entry(ptr, type, member) \
            container_of(ptr, type, member)
     
    #define list_for_each(pos, head) \
            for (pos = (head)->next; pos != (head); \
    	                pos = pos->next)
     
    #define list_for_each_entry(pos, head, member)                          \
            for (pos = list_entry((head)->next, typeof(*pos), member);      \
                 &pos->member != (head);        \
                 pos = list_entry(pos->member.next, typeof(*pos), member))
    Et la je fais . Est-ce que quelqu'un pourrait m'expliquer le sens de la premiere macro, car celle-la, elle me pose vraiment du mal. La personne qui l'aurait tape se serait inspire du code du kernel de Linux.C'est un code assez beau pour permettre de d'inserer un element dans une liste chainee. Maintenant, je commence a comprendre la puissance des macros.
    Merci d'avance.

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Salut,

    Tout d'abord, ce n'est pas du C standard. On retrouve l'opérateur typeof comme extension de gcc (probablement aussi avec d'autres compilateurs, mais je ne connais pas).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typeof( ((type *)0)->member )
    Cette expression retourne le type du membre member de la structure type. Pour déterminer ce type, on utilise une instance hypothétique de la structure type située à l'adresse 0 en mémoire. Il n'y a ici pas de déréférencement, car l'expression ((type *)0)->member n'est pas évaluée avec l'opérateur typeof.

    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct Point {
        int x;
        int y;
    };
     
    /* ... */
     
    typeof( ((struct Point *)0)->x) *__mptr;
    Ce qui équivalent à déclarer:
    Ensuite, on initialise encore __mptr avec la valeur de ptr.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})
    La deuxième ligne de la macro sert à calculer l'adresse de la structure dont member est un membre en fournissant l'adresse de member. Pour ce faire, on soustrait à l'adresse contenue dans __mptr l'offset de member au sein de la structure type via la macro standard (définie dans stddef.h) offsetof().

    Thierry

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    La même chose, sans utiliser typeof (GNU C):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <stddef.h>
     
    /* ... */
     
    #define container_of(ptr, type, member) ({ \
    const void *__mptr = (ptr); \
    (type *)((char *)__mptr - offsetof(type,member) );})
    Thierry

  4. #4
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 21
    Points : 23
    Points
    23
    Par défaut Re: probleme de comprehension de macros
    Bonjour,
    merci pour cette indication, mujigka. Cela m'a enfin permis de compiler le programme avec gcc qui me renvoyait toujours une erreur avec typeof. Cette extension de C99 est à manier avec précaution et doit dépendre des compilateurs puisque le même code pour la personne qui l'a tapé est compilable.
    Johnny.
    La même chose, sans utiliser typeof (GNU C):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <stddef.h>
     
    /* ... */
     
    #define container_of(ptr, type, member) ({ \
    const void *__mptr = (ptr); \
    (type *)((char *)__mptr - offsetof(type,member) );})

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jro-daemon
    Cela m'a enfin permis de compiler le programme avec gcc qui me renvoyait toujours une erreur avec typeof. Cette extension de C99 est à manier avec précaution et doit dépendre des compilateurs puisque le même code pour la personne qui l'a tapé est compilable.
    • offsetof() est une macro qui existe depuis C90 (<stddef.h>)
    • typeof n'est pas C99, mais GNUC.
    Il est clair qu'utiliser une extension est la meilleure façon de rendre son code non portable...

  6. #6
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 21
    Points : 23
    Points
    23
    Par défaut Probleme de comprehension de macros
    Bonjour,
    merci pour ces indications Emmanuel. Je reflichirais a partir avant d'ecrire de telles sottises. Il est vrai qur je me melange un peu les pinceaux.
    Cordialement,
    Johnny

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

Discussions similaires

  1. [vba-e] probleme de declenchement de macro excel
    Par clarkk dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 28/07/2006, 19h29
  2. [VBA-E]probleme d'integration de Macro.
    Par Stef784ever dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 08/06/2006, 01h25
  3. Probleme de comprehension de code
    Par joxbl dans le forum Langage
    Réponses: 2
    Dernier message: 30/05/2006, 19h58
  4. Probleme d'enregistrement sur Macro/VBA de Excel
    Par life is magic dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 28/11/2005, 17h23
  5. [ADODB]probleme de comprehension
    Par flogreg dans le forum ASP
    Réponses: 2
    Dernier message: 15/11/2004, 16h15

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