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 :

EnumToString : problème de conversion


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut EnumToString : problème de conversion
    Bonjour,

    Souhaitant convertir en string des enums, j'ai suivi les étapes du lien http://www.codeproject.com/Articles/...ums-to-strings.

    Seulement, à la compilation, j'ai le warning suivant :
    ***\Test\Days.h:22: avertissement : deprecated conversion from string constant to 'char*' [-Wwrite-strings]
    Pour information, je développe sous QtCreator.

    Savez-vous comment je pourrais corriger ce problème ?

    Aussi, dans la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
    , je ne comprends pas tout à fait ce que représente "tag##ENUM_NAME". Pouvez-vous m'expliquer ?

    Merci

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    C'est une macro (évaluée par le préprocesseur, donc)

    ## à pour effet de placer dans le texte de remplacement un unique token, composé par la concaténation des deux tokens indiqué.

    ainsi, en supposant #define join(a,b) a ## b, le code int join(x,1) = 2; est strictement équivalent à int x1 = 2;pour ton warning, c'est un problème de const-correctness. a priori, c'est que tu utilise une fonction prenant un char* auquel tu donnes une constante (genre "message").

    Pour résoudre le problème, il faut soit déclarer un char[], soit changer l'argument pour être un const char* (ce qui est généralement possible, si c'est ton code)

    En ultime recours, utilise l'option -E de gcc.
    Cela devrait générer un code source préprocessé, donc sans plus de macro.
    Cela pourrait t'aider.

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Remplace char * GetString, char * gs_ etc. par des déclarations de const char *.

    je ne comprends pas tout à fait ce que représente "tag##ENUM_NAME". Pouvez-vous m'expliquer ?
    Si tu fais BEGIN_ENUM(Days), tu auras une enum de type enum tagDays avec dessus un typedef enum tagDays Days;
    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.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Merci leternel et Médinoc .

    Je comprends mieux les macros de la première condition (GENERATE_ENUM_STRINGS). Dans mon cas par contre, vu qu'il y a le warning dû à la conversion de string en const char* (#element retourne la chaîne de caractères associée?), il va plutôt évaluer les macros du "else" donc il ne va pas créer d'enum ? Pourquoi la première condition n'est pas remplie ?

    Sinon, j'ai essayé de remplacer dans l'exemple par des const char* mais pour la deuxième macro (gs_...), j'ai l'erreur :

    ***\Test\Days.h:23: erreur : use of enum 'tagDays' without previous declaration
    Pourtant, je reprends l'exemple avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    BEGIN_ENUM(Days)
    {
        DECL_ENUM_ELEMENT(sunday),
        DECL_ENUM_ELEMENT(monday),
        DECL_ENUM_ELEMENT(tuesday),
        DECL_ENUM_ELEMENT(wednesday),
        DECL_ENUM_ELEMENT(thursday),
        DECL_ENUM_ELEMENT(friday),
        DECL_ENUM_ELEMENT(saturday)
    }
    END_ENUM(Days)

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Comme l'indique le code, selon des defines, le code utilisera la version du #if ou celle du #else.

    Tu mets ta définition d'enum dans le fichier header sans définir GENERATE_ENUM_STRINGS.

    Puis tu inclus ça dans un fichier source à part, d'abord sans définir GENERATE_ENUM_STRINGS puis en le définissant (si j'ai bien compris). Ce fichier source contiendra la fonction qui retourne les strings.
    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.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    tu dois placer un "const" pour les trois mentions de char.
    les deux char* et le char []

    cela dit, ca ne résoudra pas ton problème.

    Ton problème me semble être à l'autre bout du code, dans la signature de la fonction à qui GetStringDays(…) est donnée en argument.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Oui bien sûr, je comprends la démarche.

    Dans l'exemple, on voit d'ailleurs clairement le fichier source EnumToString qui appelle la macro GENERATE_ENUM_STRINGS donc pourquoi on se trouve dans l'autre condition ?

    C'est d'ailleurs bien cette deuxième condition qui me génère un warning car si je la commente, je n'ai plus de problèmes.
    Bien sûr, le mieux serait de corriger ce warning et de savoir dans quelle condition cette deuxième suite de macro peut être utile. Pour l'instant, ces deux points restent problématiques.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Peux-tu poster ton code exact?
    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.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Bien sûr, il est joint à cette réponse

    Ton problème me semble être à l'autre bout du code, dans la signature de la fonction à qui GetStringDays(…) est donnée en argument.
    La macro pour le GetString a l'air pourtant correcte. Surtout que je ne l'ai pas modifié depuis.
    Fichiers attachés Fichiers attachés

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Chez moi avec MFC et sans Unicode, ces trois fichiers sources compilent parfaitement sous Visual 2005.

    Et cette version du tester marche sans MFC:
    Code C++ : 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
    #include <iostream>
    #include <tchar.h>
    #include "Days.h"
    using namespace std;
     
    void MyFunction( Days day );
     
    int _tmain(int argc, _TCHAR* argv[], _TCHAR* envp[])
    {
    	int nRetCode = 0;
     
    	Days currentDayOfWeek = tuesday; //But for me, it was Tuesday.
    	MyFunction( currentDayOfWeek );
     
    	(cout  << "Presser [Entree] pour quitter: ").flush();
    	int n;
    	cin >> n;
     
    	return nRetCode;
    }
     
    void MyFunction( Days day )
    {
    	switch( day )
    	{
    		case monday:
    		case tuesday:
    		case wednesday:
    		case thursday:
    		case friday:
    		{
    			cout << "Today is " << GetStringDays(day) << ", I have to work!" << endl;
    		}
    		break;
     
    		case saturday:
    		case sunday:
    		{
    			cout << "Today is " << GetStringDays(day) << ", very nice!!!" << endl;
    		}
    		break;
    	}
    }
    Avec ou sans la modif const du header:
    Code C/C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // File name: "EnumToString.h"
    #undef DECL_ENUM_ELEMENT
    #undef BEGIN_ENUM
    #undef END_ENUM
     
    #ifndef GENERATE_ENUM_STRINGS
        #define DECL_ENUM_ELEMENT( element ) element
        #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
        #define END_ENUM( ENUM_NAME ) ENUM_NAME; const char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);
    #else
        #define DECL_ENUM_ELEMENT( element ) #element
        #define BEGIN_ENUM( ENUM_NAME ) const char* gs_##ENUM_NAME [] =
        #define END_ENUM( ENUM_NAME ) ; const char* GetString##ENUM_NAME(enum tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; }
    #endif
    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.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Chez moi avec MFC et sans Unicode, ces trois fichiers sources compilent parfaitement sous Visual 2005.
    Je n'ai aucun problème aussi à le faire fonctionner sous VS2010.

    Le problème intervient lorsque je développe avec l'environnement de développement QtCreator en fait.

    Sur le même projet simpliste disponible ci-joint, j'ai exécuté sous VS2010 puis sous QtCreator. Les deux captures d'écran réalisées montrent la différence..
    Images attachées Images attachées   
    Fichiers attachés Fichiers attachés

  12. #12
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    J'ai le même problème avec GCC -Wall -Wextra -Werror.

    Cela dit, j'imagine que le compilo de visual possède une option similaire.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    ... Il n'y a pas de ligne 26 dans days.h.
    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.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ah, j'ai pigé! g++ n'apprécie pas une déclaration de fonction prenant une enum en paramètre si l'enum n'est pas définie avant (et le pire, c'est qu'il me semble que le standard est d'accord avec lui).

    Essaie en changeant EnumToString.cpp comme ceci:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // File name: "EnumToString.cpp"
     
    /// The strings associated with the enums are gererated here
    /////////////////////////////////////////////////////////////////////
    #include "Days.h"
    //#include "OtherEnum.h"
    //#include "AnotherOne.h"
     
    #define GENERATE_ENUM_STRINGS  // Start string generation
    #include "Days.h"
    //#include "OtherEnum.h"
    //#include "AnotherOne.h"
    #undef GENERATE_ENUM_STRINGS   // Stop string generation
    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.

  15. #15
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    Ca a l'air mieux, en effet.
    C'est "marrant" que je ne l'ai pas vu avec gcc -E

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Ah, j'ai pigé! g++ n'apprécie pas une déclaration de fonction prenant une enum en paramètre si l'enum n'est pas définie avant (et le pire, c'est qu'il me semble que le standard est d'accord avec lui).
    Bien vu Medinoc , ça fonctionne enfin correctement!

    Merci beaucoup à vous deux pour votre aide .

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ah, j'ai pigé! g++ n'apprécie pas une déclaration de fonction prenant une enum en paramètre si l'enum n'est pas définie avant (et le pire, c'est qu'il me semble que le standard est d'accord avec lui).
    Idem pour Visual C++.

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La version 2005, celle sous laquelle j'ai testé le code, l'accepte sans discuter.

    Edit: ↓Oui, 2010 respecte mieux les standards il me semble.
    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.

  19. #19
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Il me semble pourtant avoir eu le problème il y a quelques jours sur VS 2010.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Bonjour,

    Toujours sur le même sujet, avec un exemple simple visible sur http://www.codeproject.com/Articles/...ums-to-strings, j'ai du mal à comprendre l'intérêt des directives suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // File name: "Days.h"
    #if ( !defined(DAYS_H) || defined(GENERATE_ENUM_STRINGS) )
     
    #if (!defined(GENERATE_ENUM_STRINGS))
        #define DAYS_H
    #endif
    Surtout concernant la première double condition avec en deuxième partie defined(GENERATE_ENUM_STRINGS). Admettons que le header soit déjà définie, si c'est en cours de génération de string, la première double condition sera remplie pour sortir juste après ?

    Aussi, dans EnumToSting, on aurait envie d'ajouter les directives
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #ifndef ENUMTOSTRING_H
    #define ENUMTOSTRING_H
    pour pas que le fichier soit parcouru à chaque inclusion (chaque nouveau header qui définit une nouvelle énumération...). Mais quand on fait ça, on obtient l'erreur suivante :

    erreur : multiple definition of 'enum tagDays'
    Quelqu'un pourrait m'éclairer un peu sur le comportement ?

    Merci

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

Discussions similaires

  1. problème de conversion de dimension dans BUSINESS OBJECT
    Par greatmaster1971 dans le forum Deski
    Réponses: 4
    Dernier message: 28/04/2014, 13h15
  2. - [CAST ou CONVERT] Problème de conversion de date
    Par Boublou dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 06/07/2004, 14h31
  3. Problème de conversion 3DS->.X
    Par JBernn dans le forum DirectX
    Réponses: 5
    Dernier message: 08/04/2004, 19h08
  4. Problème de conversion unicode
    Par djmalo dans le forum C
    Réponses: 5
    Dernier message: 09/03/2004, 11h48
  5. Réponses: 11
    Dernier message: 02/09/2003, 14h20

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