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 :

que fait cette fonction ?


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut que fait cette fonction ?
    Bonjour, en reprenant un code, je suis tombé sur ce morceau.

    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
     
    /*  assume 32 bit int  */
     
     typedef int int32_t;
    typedef unsigned int u_int32_t;
     
    /*  assume little endian  */
     typedef union 
     {
       double value;
       struct 
       {
        u_int32_t lsw;
        u_int32_t msw;
     } parts;
     } ieee_double_shape_type;
     
     
     /* Get the more significant 32 bit int from a double.  */
     
     #define GET_HIGH_WORD(i,d)                                      \
     do {                                                            \
       ieee_double_shape_type gh_u;                                  \
       gh_u.value = (d);                                             \
      (i) = gh_u.parts.msw;                                         \
     } while (0)
    Que veut dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    gh_u.value = (d);                                             \
    (i) = gh_u.parts.msw;
    Merci.

  2. #2
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Hello,

    Citation Envoyé par salseropom
    Bonjour, en reprenant un code, je suis tombé sur ce morceau.

    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
     
    /*  assume 32 bit int  */
     
     typedef int int32_t;
    typedef unsigned int u_int32_t;
     
    /*  assume little endian  */
     typedef union 
     {
       double value;
       struct 
       {
        u_int32_t lsw;
        u_int32_t msw;
     } parts;
     } ieee_double_shape_type;
    Ici, on a flottant en double précision (64 bits selon norme IEEE machin apparement) dont on peut aussi extraire les 32 bits de poids fort et les 32 bits de poids faible via une union.

    Citation Envoyé par salseropom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
     /* Get the more significant 32 bit int from a double.  */
     
     #define GET_HIGH_WORD(i,d)                                      \
     do {                                                            \
       ieee_double_shape_type gh_u;                                  \
       gh_u.value = (d);                                             \
      (i) = gh_u.parts.msw;                                         \
     } while (0)
    Que veut dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    gh_u.value = (d);                                             \
    (i) = gh_u.parts.msw;
    Merci.
    Tout simplement, cela veut dire qu'on met dans i les 32 bits de poids fort d'un double d, les parenthèses étant là pour éviter des surprises car il s'agit d'une macro.
    On affecte d'abord au champ de type double value de l'union gh_u le double d, puis on récupère ls 32 bits de poids forts de ce double via le champ msw de la structure parts.

    Je doute fortement que ce soit portable, rien qu'à cause de l'endianess (petit-boutien ici).

    A+
    Foobar1329

  3. #3
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    lsw = less significant word
    msw = most significant word

    i = integer
    d= double

    Je crois que la "fonction" GET_HIGH_WORD retourne a la place de i le most significant word quand on lui met un d.

    En résumé cette fonction split un double en deux int: Get the more significant 32 bit int from a double.

    En passsant, je ne sais pas si c'est première fois que tu vois ça, quand on utilise un define sa veut juste dire que le compilateur va remplacer tout les GET_HIGH_WORD() par la macro. C'est un peux comme faire un copier-coller du bout de code.
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Re, merci de vos réponses.
    Crayon, j'avais compris le principe du "copier -coller" d'un #define (même si ce #define est un peu plus compliquer que simplement #define TOTO 20 par exemple)

    Merci pour vos renseignements mais j'ai encore qq trucs qui me gênent :

    1) ma machine est sur 64 bits. Comment faire pour que la fonction marche ? Est-ce que je peux enlever les typedef et mettre simplement int ou unsigned int à la place et non plus le int32_t ?

    2) si le code n'est pas portable, comment faire pour le rendre portable ?

    j'ai chopé ce code sur le net http://www.ks.uiuc.edu/Research/namd...8C-source.html et j'avoue que toute la suite de ce code me parait plus qu'obscure...

    Merci. je comprends déjà un peu mieux le code.

  5. #5
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Ce genre de code est exactement ce qu'il faut écrire si on veut avoir des surprises lors de l'exécution. Je m'explique.

    On n'a, du moins en C-ANSI, aucune garantie que les membres msw et lsw de la structure anonyme déclarée soient effectivement adjacents en mémoire. En effet, les implantations de la norme ont le droit explicite d'intercaler des zéros entre deux membres d'une même structure, ce qui ferait que le type de la structure anonyme serait plus long qu'un double... donc Bye ! Bye ! pour récupérer les mots de poids fort et de poids faible !

    Cependant, on a deux garanties : les zéros, si ils existent, sont comptabilisés dans la taille du type, et le premier membre d'une structure et tous les membres d'une union sont bien callés "à gauche", c'est-à-dire qu'un pointeur sur une structure doit pointer vers le premier membre et pareillement pour tous les membres d'une union. Ceci veut dire que, si dans ton cas la taille de la structure égale la taille d'un double, alors le programme fonctionnera nécessairement.

    Avant d'exécuter ce genre de code, je te conseille d'essayer ceci, pour être sûr de ne pas avoir de surprises.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include <assert.h>
     
    struct double_decomposition { u_int32_t lsw; u_int32_t msw; };
     
    assert(sizeof(double) == sizeof(struct double_decomposition));
    Si ton programme avorte, alors fouts ce code à la poubelle et tente autre chose ; sinon, tu es assuré que ton programme fonctionnera correctement, si tant est que le compilateur respecte la norme ANSI (mais en principe il devrait)...

    Mais ne me fais pas dire ce que je n'ai pas dit ; entre autres, tu es assuré de récupérer les bits de poids fort grâce à msw, mais tu n'es en aucun cas assuré que ce sont réellement les bits de poids fort de la représentation IEEE !!! car celà dépend de la représentation Big Endian ou Little Endian.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  6. #6
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Une dernière chose : enlève le...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do
    {
       /* ... */
    }
    while(0)
    ... et remplace-le par uniquement un bloc : la norme ANSI autorise l'utilisation de blocs partout où l'on peut utiliser une expression composée.

    Comme ça, c'est plus propre et moins obscur !
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  7. #7
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par InOCamlWeTrust
    Une dernière chose : enlève le...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do
    {
       /* ... */
    }
    while(0)
    ... et remplace-le par uniquement un bloc : la norme ANSI autorise l'utilisation de blocs partout où l'on peut utiliser une expression composée.
    Comme ça, c'est plus propre et moins obscur !
    Oui, mais du coup, est-ce qu'on peut toujours mettre un ";" après l'appel à la macro dans le code ?
    [alkama] quelqu'un est allé voir la guerre des mondes?
    [@Chrisman] j'espère pour spielberg
    --- bashfr.org

  8. #8
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Hello,

    Citation Envoyé par salseropom
    Re, merci de vos réponses.
    Crayon, j'avais compris le principe du "copier -coller" d'un #define (même si ce #define est un peu plus compliquer que simplement #define TOTO 20 par exemple)

    Merci pour vos renseignements mais j'ai encore qq trucs qui me gênent :

    1) ma machine est sur 64 bits. Comment faire pour que la fonction marche ? Est-ce que je peux enlever les typedef et mettre simplement int ou unsigned int à la place et non plus le int32_t ?
    L'implémentation compte tout autant que la machine. Ce n'est pas parce que ta machine est sur 64 bits que les int de ton implémentation seront sur 64 bits. Ici en l'occurence, ce qui est fait strictement au niveau fonctionnel, c'est récupérer les 32 bits de poids fort et les 32 bits de poids faible d'un flottant qui est sur 64 bits (et dont le format est régi par une normr, IEEE machin bidule je sais plus). Donc, il faut pouvoir ensuite récupérer 2 fois 32 bits. Pour cela, on choisira le ou les types adéquats, int et unsigned int par exemple sous Windows, mais ça peut être autre chose (long) avec une autre implémentation. par conséquent, conseil : NE PAS ENLEVER LES TYPEDEF.

    Citation Envoyé par salseropom

    2) si le code n'est pas portable, comment faire pour le rendre portable ?
    Il faut procéder en plusieurs phases :
    1- identifier les plates-formes sur lesquelles le programme doit fonctionner
    2- identifier les implémentations C utilisées sur chaque plate-forme.
    3- se faire un fichier types.h par exemple qui définit des types équivalents, comme par exemple uint32, qui sera un entier non signé sur 32 bits, sera un unsigned int la plupart du temps, mais pourra être un unsigned long sur certaines plates-formes.
    4- gérer les problèmes d'endianess, plus compliqué, surtout quand il y a des unions contenant des structures comme ici, va falloir intervertir les bytes des variables.

    Exple simple sur un entier non signé de 32 bits, à appliquer sur les champs msw et lsw de la structure parts 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
    16
    17
    18
    19
    20
    #include <limits.h>
    #if (CHAR_BIT != 8)
    #error "Dsl, non supporte"
    #endif
    typedef unsigned int uint32;
    typedef unsigned char byte;
     
    void InvertBytesOfUint32(uint32 * val)
    {
        uint32 tmp = 0u;
        byte b0 = (byte)*val; *val >> CHAR_BIT;
        byte b1 = (byte)*val; *val >> CHAR_BIT;
        byte b2 = (byte)*val; *val >> CHAR_BIT;
        byte b3 = (byte)val; 
        tmp = b0; tmp << CHAR_BIT;
        tmp |= b1; tmp << CHAR_BIT;
        tmp |= b2; tmp << CHAR_BIT;
        tmp |= b3;
        *val = tmp;
    }
    Citation Envoyé par salseropom

    j'ai chopé ce code sur le net http://www.ks.uiuc.edu/Research/namd...8C-source.html et j'avoue que toute la suite de ce code me parait plus qu'obscure...

    Merci. je comprends déjà un peu mieux le code.
    A+
    Foobar1329

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Re,
    J'ai donc enlevé les do et les while(0).
    InOCamlWeTrust, j'ai bien testé ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include <assert.h>
     
    struct double_decomposition { u_int32_t lsw; u_int32_t msw; };
     
    assert(sizeof(double) == sizeof(struct double_decomposition));
    et ça marche. Mais rien ne dit que cela marchera sur un autre PC donc ce code n'est pas portable.

    L'union extrait les 32 bit de poids fort et faible. Cela suppose que je suis en 64 bits non ? Et si j'ai un PC 32 bits, quel sera le résultat ? Là, je ne suis pas du tout le roi de la représentation des nombres en machine.

    Merci de vos explications en tous les cas.

  10. #10
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Re-Hello,

    Citation Envoyé par salseropom
    Re,
    J'ai donc enlevé les do et les while(0).
    InOCamlWeTrust, j'ai bien testé ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include <assert.h>
     
    struct double_decomposition { u_int32_t lsw; u_int32_t msw; };
     
    assert(sizeof(double) == sizeof(struct double_decomposition));
    et ça marche. Mais rien ne dit que cela marchera sur un autre PC donc ce code n'est pas portable.

    L'union extrait les 32 bit de poids fort et faible. Cela suppose que je suis en 64 bits non ? Et si j'ai un PC 32 bits, quel sera le résultat ? Là, je ne suis pas du tout le roi de la représentation des nombres en machine.

    Merci de vos explications en tous les cas.
    Si le assert() ne sort pas, cela veut dire qu'il n'y a pas de padding dans la structure, i.e que lsw et msw sont bien adjacents en mémoire. Il s'agit surtout désormais de réglages au niveau de l'alignement des champs dans structures, disponibles avec la plupart des compilateurs. Ici, a priori, avec 2 variables de 32 bits, pas trop de souci, et si il y a beaucoup de code dans ce style, on privilègera le réglage au niveau de la compilation, car de toute façon, ce n'est pas du code portable et la réécriture pour être portable plusieurs plates-formes sera (très) fastidieuse.

    A+
    Foobar1329

  11. #11
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par InOCamlWeTrust
    Une dernière chose : enlève le...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do
    {
       /* ... */
    }
    while(0)
    ... et remplace-le par uniquement un bloc
    Le do ... while(0) assure, entre autre, que le point-virgule place apres la macro n'entraine pas d'erreur de compilation. Et ne pas mettre de point-virgule est une mauvaise pratique.

  12. #12
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Holalala, personne n'a encore vu le code pourri que j'ai produit plus haut aujourd'hui, grosse fatigue...

    Citation Envoyé par Foobar1329


    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
    #include <limits.h>
    #if (CHAR_BIT != 8)
    #error "Dsl, non supporte"
    #endif
    typedef unsigned int uint32;
    typedef unsigned char byte;
     
    void InvertBytesOfUint32(uint32 * val)
    {
        uint32 tmp = 0u;
        byte b0 = (byte)*val; *val >> CHAR_BIT;
        byte b1 = (byte)*val; *val >> CHAR_BIT;
        byte b2 = (byte)*val; *val >> CHAR_BIT;
        byte b3 = (byte)val; 
        tmp = b0; tmp << CHAR_BIT;
        tmp |= b1; tmp << CHAR_BIT;
        tmp |= b2; tmp << CHAR_BIT;
        tmp |= b3;
        *val = tmp;
    }
    Replacement, ça marche mieux comme ça :

    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
    #include <limits.h>
    #if (CHAR_BIT != 8)
    #error "Dsl, non supporte"
    #endif
    typedef unsigned int uint32;
    typedef unsigned char byte;
     
    void InvertBytesOfUint32(uint32 * val)
    {
        uint32 tmp = 0u;
        byte b0, b1, b2, b3;    
     
        b0 = (byte)*val; *val >>= CHAR_BIT;
        b1 = (byte)*val; *val >>= CHAR_BIT;
        b2 = (byte)*val; *val >>= CHAR_BIT;
        b3 = (byte)val; 
     
        tmp = b0; tmp <<= CHAR_BIT;
        tmp |= b1; tmp <<= CHAR_BIT;
        tmp |= b2; tmp <<= CHAR_BIT;
        tmp |= b3;
     
        *val = tmp;
    }
    A+

  13. #13
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par salseropom
    Re,
    J'ai donc enlevé les do et les while(0).
    InOCamlWeTrust, j'ai bien testé ton code :

    ...

    et ça marche. Mais rien ne dit que cela marchera sur un autre PC donc ce code n'est pas portable.
    Effectivement, rien ne dit que ça marchera sur un autre PC, mais si tu insères ces trois petites lignes au début du programme, par exemple, tu seras au moins sûr de récupérer les bits de poids fort et les bits de poids faible si le programme n'avorte pas.

    Ensuite, je te conseille de regarder dans un des fichiers .h standards, par exemple stddef.h, pour voir quel est le type 32 bits défini (un truc dans le genre u_int32_t, ou appareillé). Ces fichiers existent sur toutes les machines mais ont au moins le bon goût d'être dépendants de l'implantation.

    Si tu ne parviens toujours pas à trouver le bon type 32 bits, et bien vas-y à la bourrin. Ecris un code contenant uniquement ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include <stddef.h> 
    #include <stdio.h> /* au cas ou... */
    #include <stdlib.h>
    puis compile mais en t'arrêtant juste après la phase du pré-processeur ; avec gcc, c'est l'option -E, avec les autres, tu devrais trouver une option similaire dans la doc. A noter aussi qu'il existe une option spéciale, parfois, permettant de sortir directement un fichier avec toutes les déclarations, ce qui peut être plus pratique ici. Si tu es très préoccupé par la portabilité, active (sous gcc) l'option -ansi qui perment de définir la macro _STRICT_ANSI : celà élimine les déclarations non portables si les .h sont bien foutus, car il leur revient le rôle de reconnaître cette macro et d'adapter les déclarations en conséquence.

    Une fois que tu as récupéré le fichier avec toutes les macros développées, regarde si tu ne trouves pas un type de nom comme celui indiqué plus haut, puis regarde le qui est juste au-dessus pour connaître le fichier le définissant.

    Désolé, mais en C, les compilateurs peuvent faire ce qu'ils veulent avec la représentation des entiers, bien que normalement sur les PC 32 bits les int sont bien 32 bits... mais ne te fie pas trop tout de même.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  14. #14
    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 InOCamlWeTrust
    Une dernière chose : enlève le...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do
    {
       /* ... */
    }
    while(0)
    ... et remplace-le par uniquement un bloc : la norme ANSI autorise l'utilisation de blocs partout où l'on peut utiliser une expression composée.

    Comme ça, c'est plus propre et moins obscur !
    C'est obscur si on en connait pas la raison. Cette manip un peu étrange est faite dans une définition de macro pour forcer l'usage du ';' lors de "l'appel" de la macro-fonction.

    Ce que tu préconises autorise un "appel" sans ';', ce qui, bien que techniquement correct, est troublant pour un relecteur de base (le gars de la qualité qui relit le code n'est pas forcément un gourou de niveau 3...) ou un indenteur automatique.
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    OK. Merci de toutes vos remarques.

  16. #16
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    C'est obscur si on en connait pas la raison. Cette manip un peu étrange est faite dans une définition de macro pour forcer l'usage du ';' lors de "l'appel" de la macro-fonction.
    Tu oublies une chose : l'instruction vide...

    ... est une instruction valable, donc on a tout à fait le droit d'en mettre après un bloc. Syntaxiquement et sématiquement parlant, elle n'a pas le même statut que le ";" après le "while", mais c'est tout à fait correct.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  17. #17
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par InOCamlWeTrust
    Tu oublies une chose : l'instruction vide...

    ... est une instruction valable, donc on a tout à fait le droit d'en mettre après un bloc. Syntaxiquement et sématiquement parlant, elle n'a pas le même statut que le ";" après le "while", mais c'est tout à fait correct.
    Mais parfois on se fait jeter par le compilateur en faisant comme ça. Ca m'est déjà arrivé.
    [alkama] quelqu'un est allé voir la guerre des mondes?
    [@Chrisman] j'espère pour spielberg
    --- bashfr.org

  18. #18
    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 InOCamlWeTrust
    Tu oublies une chose : l'instruction vide...
    ... est une instruction valable, donc on a tout à fait le droit d'en mettre après un bloc. Syntaxiquement et sématiquement parlant, elle n'a pas le même statut que le ";" après le "while", mais c'est tout à fait correct.
    Certes, mais on est pas obligé de la mettre, alors qu'avec un do-while(0) sans ; dans une macro, on est obligé de mettre le ';' lors de "l'appel" pour être syntaxiquement correct. C'est une pratique très courante et justifiée qu'il est difficile de remettre en cause.
    Pas de Wi-Fi à la maison : CPL

  19. #19
    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
    Manque de pot, certains compilos (Visual) ne détectent pas cette pratique dans les modes les plus paranos (Warning niveau 4) et sortent un Warning pour condition constante...
    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.

  20. #20
    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
    Citation Envoyé par InOCamlWeTrust
    Tu oublies une chose : l'instruction vide...

    ... est une instruction valable, donc on a tout à fait le droit d'en mettre après un bloc. Syntaxiquement et sématiquement parlant, elle n'a pas le même statut que le ";" après le "while", mais c'est tout à fait correct.
    Tu oublies qu'il s'agit d'une macro. Si tu utilises cette technique, le ; que tu mets après la macro peut avoir des effets indésirés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (cond)
       maMacroUtilisantSimplementUnBloc();
    else /* erreur de syntaxe */
       ...
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. que fait cette fonction(5 lignes)
    Par router_ dans le forum Débuter
    Réponses: 4
    Dernier message: 14/06/2010, 08h52
  2. Réponses: 9
    Dernier message: 18/06/2009, 19h31
  3. Que fait cette fonction ?
    Par Invité(e) dans le forum C++Builder
    Réponses: 5
    Dernier message: 05/05/2008, 20h40
  4. que fait cette fonction ?
    Par nitteo dans le forum C#
    Réponses: 21
    Dernier message: 31/01/2008, 17h30
  5. Que fait cette fonction ?
    Par masterix59 dans le forum Débuter
    Réponses: 2
    Dernier message: 16/11/2007, 21h13

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