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 :

Commenter automatiquement une ligne en fonction d'une variable préprocesseur


Sujet :

C++

  1. #1
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut Commenter automatiquement une ligne en fonction d'une variable préprocesseur
    Bonjour,

    A votre avis, est-il possible de commenter automatiquement une ligne du style:
    en fonction d'une variable préprocesseur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #ifndef _DEBUG
       #define Log(DEBUG) //
    #endif
    Bien sûr ici ça ne fonctionnera pas car // va être interpréter par le compilateur comme un début de commentaire... Vous voyez ce que je veux faire?

    Un grand merci d'avance!

  2. #2
    Membre habitué Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Points : 185
    Points
    185
    Par défaut
    Tout depend de ce que fais ta ligne a commenté, mais pour ce genre de choses, une macro me semble bien adaptée

    Par exemple une macro qui fait un printf :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifdef DEBUG_FLAG
    #define DEBUGOUTPUT(A)  printf("%d",A); //definition de la macro DEBUG OUTPUT
    #else
    #define DEBUGOUTPUT(A)  //on remplace les DEBUGOUTPUT par...du vide ! 
    #endif

  3. #3
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Salut Ksempac,

    Le problème c'est que dans le define, le // va être interprêté par le compilateur comme un compilateur donc va être éliminé...

  4. #4
    Membre habitué Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Points : 185
    Points
    185
    Par défaut
    Le // n'est la que pour commenter ce que j'ai ecrit. Le code sans commentaires est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifdef DEBUG_FLAG
    #define DEBUGOUTPUT(A)  printf("%d",A);
    #else
    #define DEBUGOUTPUT(A)  
    #endif

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    deux avis:

    - les macros c'est le mal, au pire fait un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    #define DEBUG
    //...
    #ifdef DEBUG
       //code de debug
    #endif
    si vraiment tu tiens à le définir à la compilation...

    - pour un code professionel:

    le débug, ça peut être important, quand ce sera en production tu en auras peut être besoin sans pouvoir tout recompiler. Dans ce cas là il vaut mieux pouvoir le définir à l'éxécution ( dans la ligne de commande par exemple, ou fichier de configuration ou autre...)

  6. #6
    Membre habitué Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Points : 185
    Points
    185
    Par défaut
    C'est vrai que les macros c'est dangereux. Mais je pense que la premiere solution que tu proposes n'est pas vraiment adaptée : Si la ligne qu'il veut supprimer apparait regulierement dans son code (ce qui semble etre le cas car on dirait un systeme de traces/log) il faut ecrire partout des :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #ifdef DEBUG
     // code de debug
    #endif
    Ceci est assez lourd.

    Avec la Macro tu n'as pas ce probleme. L'important est de bien nommé la Macro pour que le fait que c'est une macro saute aux yeux de suite et qu'il n'y ait pas de confusion (typiquement avec un nom en majuscules du genre DEBUGMONFICHIER(A)).

    En ce qui concerne la définition "à la volée" durant l'exécution, c'est sur que c'est une très bonne idée, mais il faut voir si ca correspond a ces besoins.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    si son debug doit apparaître de nombreuses fois dans le code, de manière permanente, ce devrait être la fonction de log qui décide si elle doit afficher ou pas le message, et non un choix à la compilation.

    Je ne sais pas si c'est très clair ce que je dis

    Comme on est sur le forum C++, on va dire non aux macros Ce serait sur le forum C...

  8. #8
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Dans l'absolu je suis d'accord avec nikko... si c'est pour logger des informations, alors le code devrait resembler à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (log.isDebugEnabled())
        log.debug(.....);
    Si c'est pour executer des choses différentes... alors oui, le define est la seule solution...

    Sous Visual par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifdef _DEBUG
    #define DEBUG_ONLY(...)      __VA__ARGS__
    #else
    #define DEBUG_ONLY(...)
    #endif
    Tout ce qui sera dedans sera utilisé tel quel quand _DEBUG est défini, et n'existera pas sinon.

    Mais attention... avoir un code différent entre debug et release ne veut dire qu'une chose: tu auras des bugs qui n'apparaitront qu'en mode release !

  9. #9
    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
    Citation Envoyé par Rodrigue
    Salut Ksempac,

    Le problème c'est que dans le define, le // va être interprêté par le compilateur comme un compilateur donc va être éliminé...
    Encore que, je suis tombé sur un drôle de hack dans Visual, pas plus tard qu'hier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #if UNEMACRO
    #define UNEAUTREMACRO /##/
    #else
    #define UNEAUTREMACRO
    #endif
     
    //...
     
    {
       //...
       UNEAUTREMACRO UneInstruction();
       //...
    }
    //...
    Je me demande si gcc accepte un truc du genre, mais puisqu'il existe une option "keep comments" dans le préprocesseur de gcc, il y a fort à penser que ça marche aussi...

    Edit: Sous Visual, pas moyen de le faire marcher avec des commentaires C : J'ai beau tenter diverses combinaisons, la macro de fin n'est jamais remplacée...

    Edit2: Réussi!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #if UNEMACRO
    #define MACROA /##*
    #define MACROB
    #else
    #define MACROA
    #define MACROB /##*
    #endif
     
    void TestMacro(void) 
    {
    	puts("A");
    	MACROA puts("B"); MACROB */
    	puts("C");
    }
    Je teste sous GCC à présent...

    Edit3: Échec sous gcc:
    Citation Envoyé par cpp, gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)
    pasting "/" and "/" does not give a valid preprocessing token
    Et on se retrouve avec un espace entre les deux caractères, que ce soit pour les commentaires C++ ou les commentaires C...

  10. #10
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Magnifique Médinoc! Je viens d'essayer sur un exemple simple et le coup du /##/ (qu'au passage je connaissais pas et dont je ne trouve aucune documentation à ce sujet) a l'air de fonctionner parfaitement

    Lundi, j'essaye ça au bureau. Merci à tous!

  11. #11
    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
    Enfin, comme l'ont montré mes tests, c'est totalement non-portable (à moins que gcc 4 accepte ce hack) et à mon avis, non-standard...

  12. #12
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Concernant les log, j'ai écrit une classe similaire avec des macros faisant ce que tu veux il me semble (enfin il est ard ... donc j'ai peut-etre compris de travers) En tout cas si ca peut t'aider, voici mon fichier :

    .hpp
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
     
    #ifndef LOGGER_HPP
    #define LOGGER_HPP 
     
        // Output Type (Flags)
        #define LOG_FILE      0x00000001
        #define LOG_SCREEN    0x00000002
        #define LOG_CONSOLE   0x00000004
        #define LOG_ALL       LOG_FILE | LOG_SCREEN | LOG_CONSOLE
     
        // Msg Type (1 = Log / 0 = Don't)
        #define LOG_OK 1
        #define LOG_WARNING 1
        #define LOG_ERROR 1 
        #define LOG_MISC 1
     
        // 0 -> __FUNCTION__ macro supported ; 1 -> Define your own macro .
        #if 0
            #define __FUNCTION__ "__FUNCION__ isn't available"
        #endif
     
        // The actual logging macro.
        #define Log(flag,type) Logger<type == 1>(#type,flag,__FILE__,__FUNCTION__,__LINE__)
     
        #include <sstream>
        #include <iostream>
        #include <fstream>
    	#include <boost/algorithm/string/replace.hpp>
     
        // Template, general declaration
        template<bool DoLog> class Logger;
     
        // Template version, if we actually want to log something .
        template<> class Logger<true>
        {
            public :
     
    			Logger(const char * Type,unsigned const char Flag,const char * File,const char * Function,unsigned int Line)
    			: m_Type(Type)       ,
    			m_Flag(Flag)         ,
    			m_File(File)         ,
    			m_Function(Function) ,
    			m_Line(Line)         {}
     
    			~Logger()
    			{
    				if ( m_Flag & LOG_FILE )
    				{
    					boost::algorithm::replace_all(m_Function,"<","&lt;");
    					boost::algorithm::replace_all(m_Function,">;","&gt");
     
    					m_FileStream << "<EventLog>" << "\n" ; 
    					m_FileStream << "<Type>" << m_Type << "</Type>" << "\n" ;
    					m_FileStream << "<File>" << m_File << "</File>" << "\n" ;
    					m_FileStream << "<Line>" << m_Line << "</Line>" << "\n" ;
    					m_FileStream << "<Function>" << m_Function << "</Function>" << "\n" ; 
    					m_FileStream << "<Msg>"  << m_Msg.str()  << "</Msg>" << "\n" ;
    					m_FileStream << "</EventLog>" << "\n" << "\n" << std::flush ;
    				}
    				if ( m_Flag & LOG_SCREEN ) 
    				{ /* TODO */ }
    				if ( m_Flag & LOG_CONSOLE )
    				{ /* TODO */ } 
    			}
     
    			static void Init()
    			{ 
    				m_FileStream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << "\n" ;
    				m_FileStream << "<?xml-stylesheet type=\"text/xsl\" href=\"Log.txt\" ?>" << "\n" ;
    				m_FileStream << "<RuntimeLog>" << "\n" << "\n" ;
    				m_FileStream << "<LogHeader>" << "\n" ;
    				/* TODO : Find what i need in the LogHeader . */
    				m_FileStream << "</LogHeader>" << "\n" << "\n" << std::flush ;
    			}
     
    			static void Close()
    			{ 
    				m_FileStream << "</RuntimeLog>" << std::flush ;
    				m_FileStream.close();
    			}
     
    			template<typename T> Logger & operator << (T const & Msg) { m_Msg << Msg; return * this; }
     
            private:
     
    			std::stringstream m_Msg;
     
    			unsigned const char m_Flag ;
     
    			const char * m_File ;
     
    			const int m_Line ;
     
    			const char * m_Type ;
     
    			std::string m_Function ;
     
    			static std::ofstream m_FileStream ;
        };
     
        // Template version, if we do NOT want to log .
        template<> class Logger<false>
        {
            public :
     
    			Logger(const char * Type,unsigned const char Flag,const char * File,const char * Function,unsigned int Line){}
     
    			template<typename T> Logger & operator << (T const & Msg) { return * this; }
     
        };
     
    #endif

    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #include <Tools/Logger.hpp>
     
    // Static menber initialisation .
    std::ofstream Logger<true>::m_FileStream("Log/Log.xml") ;
    Sinon j'en parle dans un de mes anciens post sur ce forum, si tu ne le trouve pas, je le rechererai , bonne chance.

Discussions similaires

  1. [XL-2003] Remplir automatiquement une ligne en fonction d'une cellule
    Par Tonio68 dans le forum Excel
    Réponses: 8
    Dernier message: 25/03/2011, 18h51
  2. créer une macro en fonction d'une ligne particulière
    Par antfo dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 19/03/2010, 17h22
  3. [XL-2003] Supprimer une ligne en fonction d'une valeur de cellule
    Par FCL31 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 02/09/2009, 17h20
  4. Réponses: 1
    Dernier message: 10/02/2008, 19h56
  5. Recherche une ligne en fonction d'une date
    Par c+cool dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 20/09/2006, 15h30

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