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 :

Incompatibilité enum et c++ ?


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut Incompatibilité enum et c++ ?
    Bonjour,

    Je souhaite déclarer un type énuméré (enum flag {TRUE,FALSE}; ) dans un fichier Settings.h et manifestement le compilateur n'aime pas car il me crache des erreurs du genre:
    Settings.h expected identifier before numeric constant
    Settings.h expected `}' before numeric constant
    Settings.h expected unqualified-id before numeric constant
    Settings.h expected `,' or `;' before numeric constant
    Settings.h expected declaration before '}' token

    Y a-t-il une incompatibilité ?
    Bien cordialement,
    Christian

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Un petit bout de code un peu plus long?
    Parce que chez moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    enum flag {TRUE,FALSE};
    ça compile (même si je n'en vois pas trop l'intérêt).

  3. #3
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Suivant les en-têtes inclus (je pense notamment à windows.h), ça va être préprocessé en enum flag { 0, 1 }; et donc, marcher beaucoup moins bien...

    Mais pourquoi ne pas utiliser tout simplement :

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut
    Merci pour vos input.
    @3D archi : j'ai une librairie de tools dans laquelle j'ai plusieurs classes qui utilise le fichiers Settings.h. La compilation de cette librairie ne pose pas de problème. Les messages d'erreur mentionnés ci-dessus apparaissent quand je compile un programme qui utilise cette libraire.
    @white_tentacle : en fait, j'ai fait simple en posant la question mais en fait j'ai plusieurs valeurs (ERROR, NO_ERROR, WARNING, ...) et pas juste un booleen true/false

    Christian

  5. #5
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    En fait, l'erreur est quand même celle-là je pense.

    Fais tourner uniquement le préprocesseur, et regarde le code généré. Tu dois avoir un entier dans ton énumération.
    Settings.h expected identifier before numeric constant

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut
    @white_tentacle : merci pour ton aide. A la suite de quoi, j'ai supprimé les énums et mis de entiers et cela ne donne plus d'erreur.

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    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 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je ne suis pas tout à fait d'accord avec la solution : enlever enum pour mettre des entiers. Les enums sont excellent pour le cas que tu cite, et cette solution c'est ce cacher du problème de base.
    Certes je n'ai pas trouvé la solution :s , mais pour ma part je fais mes énums comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace Type
    {
    	enum
    	{
    		NO_ERROR,
    		ERROR,
    		OTHER_TYPE
    	};
    }
    Je ne sais plus si la possibilité de mettre un nom dans l'énum existe ( comme tu l'a fait )
    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.

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Surtout, ne pas mettre les enums en LETTRES_CAPITALES. C'est plutôt réservé pour les directives préprocesseurs.

    Et là, c'est typiquement ce qui s'est passé, un clash entre une directive préprocesseur et la déclaration de l'enum.

    D'ailleurs, la solution (repasser par des #define) est assez malheureuse, car la constante est désormais définie deux fois, probablement pas avec la même valeur, dans le programme.

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    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 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    On clashe avec le préprocesseur même avec le namespace ( surement oui ... :s )
    Zut, merci du conseil
    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.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    On clashe avec le préprocesseur même avec le namespace ( surement oui ... :s )
    Zut, merci du conseil
    C'est un usage qui veut qu'on mette en majuscule les directives du préprocesseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define MA_CONSTANTE 12
    // qu'on préfère remplacer en C++ par :
    static const int ma_constante = 12;

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    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 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    Peut t'on me dire l'usage d'écriture des enums, alors ?
    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.

  12. #12
    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
    J'ai tendance à les écrire 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
    namespace MyLib
    {
      enum ErrorType
      {
        errNone = 0,
        errDiskFull,
        errDuplicateKey
      };
      enum State
      {
        stateNone = 0, // Si je n'avais pas préfixé, State::None aurait été en conflit avec ErrorType::None
        stateReady
      };
    }

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,
    Le fait est que tu choisi finalement très mal le nom de tes valeur énumérées:

    True et false sont des mot clé définis, et il n'est pas exclu qu'il existe, dans un des fichier de la bibliothèque C, un #define FALSE 0 et un #define TRUE !FALSE, ce qui semble confirmé par le message d'erreur obtenu (un identifiant est attendu avant la constante numérique).

    N'hésite pas à prévoir des noms réellement explicites pour tes valeur énumérées, telles que isTrue, isFalse, HasNoError, HasError,...

    C'est, certes, plus long à écrire, mais cela permet d'atteindre le premier objectif de l'énumération qui est de fournir un nom explicite (à la lecture du code) à une valeur en vue de permettre au lecteur du code de comprendre ce que l'on teste (ou ce que l'on renvoie)
    Citation Envoyé par LittleWhite Voir le message
    <snip>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace Type
    {
    	enum
    	{
    		NO_ERROR,
    		ERROR,
    		OTHER_TYPE
    	};
    }
    Je ne sais plus si la possibilité de mettre un nom dans l'énum existe ( comme tu l'a fait )
    C'est tout à fait légal

    La seule chose, c'est que tu perd le bénéfice du deuxième objectif de l'énumération, à savoir: regrouper les différentes valeurs énumérées au sein d'un seul et même type particulier...

    En effet, lorsque tu crées une énumération sous la forme "classique" (en lui donnant un nom) de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum eMyErrorType
    {
        meNoError,
        meErrorTypeOne,
        meErrorOtherType
    };
    tu as la possibilité de déclarer une variable du type de l'énumération (ici, eMyErrorType).

    Si tu règle correctement ton compilateur, et que tu écris un test à choix multiple sur la valeur de cette variable sous une forme qui pourrait se rapprocher de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    eMyErrorType met;
    /* plus loin */
    switch (met)
    {
        case meNoError:
            /*...*/
            break;
        case meErrorTypeOne:
            /*...*/ 
            break;
        /* le case meErrorOtherType est volontairement oublié */
    };
    le compilateur devrait t'indiquer que toutes les valeurs potentielles admise pour <met> n'ont pas été gérées.

    De plus, si tu essaye de donner une valeur qui ne correspond à aucune des valeurs énumérées, le compilateur refusera la valeur indiquée.

    Si tu ne donnes pas de nom à ton énumération, la seule utilité qu'elle garde, c'est de donner des identifiant uniques à différentes constantes numériques.

    Si tu définis une énumération anonyme dans une portée globale ou dans un espace de noms, tu n'obtiens en définitive rien de bien plus utile que ce que tu peux obtenir avec un simple #define : l'identifiant de la valeur énumérée est remplacé par la valeur constante, mais ne représente aucun type auquel tu puisse faire appel et tu te trouve donc obligé de les manipuler comme s'il s'agissait d'un entier "quelconque":

    Tu peux assigner la valeur à un entier avec un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int i = valeurEnumeree;
    tu peux renvoyer la valeur énumérée lorsque la fonction doit renvoyer un entier (n'importe lequel: cela fonctionnerait si tu renvoyais un char, un short ou un long... en fonction du nombre de valeur énumérées dans l'énumération )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int foo()
    {
        /*...*/
        return valeurEnumeree;
    }
    Mais tu perd la possibilité de déclarer une variable du type précis de ton énumération (ce qui est normal vu qu'elle n'a pas de nom auquel faire référence) et, par la même, l'occasion de profiter de "l'intransigeance" du compilateur

    Ceci dit, les énumérations anonymes ont un intérêt qu'il ne faut pas négliger, mais qui ne s'exprime réellement que dans le cadre d'énumérations imbriquées dans une classe ou une structure...

    Ainsi, on peut envisager de l'utiliser pour représenter un état interne à la classe (ou à la structure) qui ne doit absolument pas être utiliser autrement que... de manière interne...

    On peut aussi, et c'est souvent le cas, l'utiliser dans des classes template pour obtenir une information de valeur, sous une forme qui pourrait être celle de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <class T>
    struct SizedStruct
    {
        typedef T type; // le type
        enum {value = sizeof(type)}; // la valeur
    };
    Dans de telle circonstances, il n'y a pas vraiment d'intérêt à disposer d'un type particulier pour l'énumération et nous n'utiliserons de toutes manière la valeur énumérée que comme... un entier

    Vous m'avez de nouveau incité à écrire un roman... J'espère qu'il sera utile pour la compréhension
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    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 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    Encore merci pour la réponse. Pardon d'incité à écrire des romans :s.
    C'est juste que je cherche à toujours faire un code meilleur, sachant que j'utilise des choses que je ne connais pas toujours les implications...
    Vraiment merci
    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.

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Peut t'on me dire l'usage d'écriture des enums, alors ?
    Là, j'ai vu différentes choses.
    Soit comme NiamrorH :

    Citation Envoyé par NiamorH Voir le message
    J'ai tendance à les écrire 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
    namespace MyLib
    {
      enum ErrorType
      {
        errNone = 0,
        errDiskFull,
        errDuplicateKey
      };
      enum State
      {
        stateNone = 0, // Si je n'avais pas préfixé, State::None aurait été en conflit avec ErrorType::None
        stateReady
      };
    }


    Soit 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
     
    namespace MyLib
    {
      enum E_ErrorType
      {
        E_err_none = 0,
        E_err_disk_full,
        E_err_duplicate_key
      };
      enum E_State
      {
        E_state_none = 0, 
        E_state_ready
      };
    }
    ou aussi :
    Soit 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
     
    namespace MyLib
    {
      enum E_ErrorType
      {
        Err_E_none = 0,
        Err_E_disk_full,
        Err_E_duplicate_key
      };
      enum E_State
      {
        State_E_none = 0, 
        State_E_ready
      };
    }
    Ou pire (ce qui aboutit au même genre de pb que présenté qu début du fil) :
    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
     
    namespace MyLib
    {
      enum ErrorType
      {
        none = 0,
        disk_full,
        duplicate_key
      };
      enum E_State
      {
        snone = 0,
        ready
      };
    }

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/05/2004, 11h40
  2. UPDATE+max= Incompatibilité?
    Par $grm$ dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 21/05/2004, 16h43
  3. enum??
    Par $grm$ dans le forum PostgreSQL
    Réponses: 10
    Dernier message: 23/04/2004, 16h34
  4. [TABLE][ENUM] u champs à choix multiple ?
    Par narmataru dans le forum SQL
    Réponses: 2
    Dernier message: 04/11/2003, 10h25
  5. problème d'incompatibilité apparement
    Par stephane eyskens dans le forum Flash
    Réponses: 8
    Dernier message: 17/09/2003, 14h51

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