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 :

Quelques questions sur des macro


Sujet :

C

  1. #1
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut Quelques questions sur des macro
    Bonjour
    J'ai besoin de comprendre les macro suivantes ainsi que leur structure


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define NewValue(ts) ((VALUE (*)(void)) (ts->New))()
    Cette macro prend un argument ts (le type de cet argument n'est pas important).
    Le corps de cette macro est: ts->New (Oui?)
    A quoi servent les parenthèses vides à la fin?
    Je ne comprends pas non plus le code de typage:
    VALUE (*)(void)
    Cela ressemble à des pointeurs sur fonctions. In fine, cette macro est-elle un pointeur sur fonction?


    je ne comprends pas du tout cette macro suivante (la deuxième partie, après les :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define ToStrValue(vc,flagShort) \
      ((vc)->ts == NULL ?  "" : \
        ((char * (*)(struct value *, char)) ((vc)->ts->ToStr)) ((VALUE) vc,flagShort))
    Merci

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define NewValue(ts) ((VALUE (*)(void)) (ts->New))()
    1. (ts->New) est casté en VALUE (*)(void)
    2. VALUE (*)(void) c'est le type "pointeur de 'fonction qui prend void comme argument et qui retourne un VALUE''.
    3. Une fois le cast fait, on appelle la fonction. Si tu ne comprends pas, note f = (VALUE (*)(void)) (ts->New). L'écriture est ensuite (f)(), qui est bien un appel de fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (char * (*)(struct value *, char)) ((vc)->ts->ToStr)) ((VALUE) vc,flagShort)
    1. (vc)->ts->ToStr est casté en char * (*)(struct value *, char)
    2. char * (*)(struct value *, char) est le type "pointeur de 'fonction qui prend un struct value * et un char comme arguments et qui retourne un char *'".
    3. Une fois le cast fait, la fonction est appelée en lui passant évidemment les arguments requis. D'après le code, VALUE est donc un typedef de struct value *.

    Voir aussi : [Tutoriel] Les déclarations complexes.

  3. #3
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Ok, c'est pas tout a fait ce que je croyais.
    En fait, comme il nous arrive de caster des objets ou des variables, il nous arrive aussi de caster des fonctions.

    L'écriture est ensuite (f)(), qui est bien un appel de fonction.
    Oui, mais ici f ne prend pas d'arguments? Cela reviendrait à écrire (f)(void)?



    Dans mon exemple, peut-on dire que la fonction ToStrValue est une référence de la fonction ToStr

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par deubelte Voir le message
    Oui, mais ici f ne prend pas d'arguments? Cela reviendrait à écrire (f)(void)?
    Non, parce que l'usage de la macro est, par exemple : VALUE v = NewValue(s); Ce qui va être transformé lors de la compilation en VALUE v = (f)();

    Quand tu appeles une fonction qui prend void comme argument, tu écris ma_fonc(); ou ma_fonc(void); ? C'est la première bien sûr.

  5. #5
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define NumExtractValue(vc,arg) \
      (((vc)->ts == NULL ? ((*((vc)->sendMessage))(vc,NumExtractMsge,arg)) : \
       ((vc)->ts->NumExtract == NULL ? NULL : \
      (*((void * (*)(struct value *,void **)) ((vc)->ts->NumExtract))) ((VALUE) (vc),(void **) (arg)))))
    j'ai une dernière question sur le code ci-dessus, après les :

    On a une fonction: vc->ts->NumExtract, qui est casté en *((void * (*)(struct value *,void **)), et qui prend en argument (VALUE) (vc),(void **) (arg).

    ((void * (*)(struct value *,void **)) est un pointeur sur fonction qui prend en argument struct value et void**.

    Donc *((void * (*)(struct value *,void **)) permet de déférencer. Donc NumExtractValue n'est cette fois-ci pas un pointeur de fonction mais une fonction réelle?
    Ok?

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Exact. Mais il faut également savoir qu'en C, ça ne sert absolument à rien de déréférencer un pointeur de fonction. Explications.

  7. #7
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    j'ai moi-même fait un test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define f3(x) ((char* (*)(char *))(fchar))(x)
     
    #define f4(x) (*(char* (*)(char *))(fchar))(x)
     
    char *fchar(char* x){
    return x;
    }
    et f4 et f3 renvoient exactement la même chose. Cela confirme bien que cela ne sert à rien de déférencer des fonctions?

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Oui !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (&printf)("Bonjour.\n");
    (printf)("Bonjour.\n");
    printf("Bonjour.\n");
    (*printf)("Bonjour.\n");
    (**printf)("Bonjour.\n");
    Tout ça aussi c'est la même chose, comme indiqué dans le lien que tu n'a pas suivi.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/09/2008, 10h48
  2. [scanners] Quelques questions sur la composition des scans.
    Par Muesko dans le forum Périphériques
    Réponses: 13
    Dernier message: 04/09/2007, 15h37
  3. Quelques questions sur des écritures en perl
    Par Premium dans le forum Langage
    Réponses: 4
    Dernier message: 05/12/2006, 23h44
  4. Quelques questions sur la gestion des droits
    Par sylsau dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 04/03/2006, 14h11
  5. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23

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