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 :

Pas d'appel à une fonction si mode Release


Sujet :

C++

  1. #1
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut Pas d'appel à une fonction si mode Release
    Bonjour à tous,

    Je développe sous VC++6 mais ma question porte plus sur le C++ que sur mon IDE.

    N'utilisant pas la MFC, j'ai voulu réécrire une petite fonction Trace() qui me permettrait d'afficher des infos sur la fenetre de debug.

    Mon problème c'est que lorsque je ne suis plus en mode débug, j'aimerais que tous les appels à ma fonction disparaissent afin de gagner de la place mais surtout de la sécurité. Et je trouve fort fastideux de mettre un #ifndef .. #endif de part et d'autre de chaque appel de ma fonction debug::print()

    Voici ma solution actuelle mais je la trouve tout sauf élégante
    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
    #ifndef _DEBUGH_
    #define _DEBUGH_
     
    #include <windows.h>
    #include <stdio.h>
     
    class debug
    {
    public:
     
    #ifdef _DEBUG
    	static void print(LPCTSTR pszString, ...)
    	{
    		TCHAR buff[1024];
    		va_list arg;
     
    		va_start(arg, pszString);
    		vsprintf(buff, pszString, arg);
    		OutputDebugString(buff);
    		va_end(arg);
    	};
    #else
    	static void print(void* a, void* b=0, void* c=0){};	// Pas très propre mais c'est la seule méthode que j'ai trouvée pour ne pas avoir un appel de fonction
    #endif
     
    };
     
    #endif
    Est-ce la seule méthode pour que mon compilateur ne génère pas de code pour ma fonction une fois que je ne suis plus en mode débug?

    J'espère avoir été assez clair

    Merci d'avance,
    Crisanar

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 41
    Points : 45
    Points
    45
    Par défaut
    Salut,

    essaye ça qui devrait arriver au même résultat, mais avec le même prototype pour ta fonction :
    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
    #ifndef _DEBUGH_
    #define _DEBUGH_
     
    #include <windows.h>
    #include <stdio.h>
     
    class debug
    {
    public:
     
       static void print(LPCTSTR pszString, ...)
       {
          #ifdef _DEBUG
          TCHAR buff[1024];
          va_list arg;
     
          va_start(arg, pszString);
          vsprintf(buff, pszString, arg);
          OutputDebugString(buff);
          va_end(arg);
          #endif
       }
    };
     
    #endif
    reste qu'en effet ce n'est pas très propre mais c'est la seul méthode que je vois. Par contre celà ne supprime pas les appels à ta fonction, juste elle ne fera rien...

    Tarrke

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ah, pour une fonction à arguments variables, c'est assez dur...

    Ce que tu peux faire, sinon, c'est une macro:
    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
    #ifndef _DEBUGH_
    #define _DEBUGH_
     
    #include <windows.h>
    #include <stdio.h>
     
    class debug
    {
    public:
     
       //fonction de debuggage (inclue dans le proto de classe, donc inline)
       static void print(LPCTSTR pszString, ...)
       {
          TCHAR buff[1024];
          va_list arg;
     
          va_start(arg, pszString);
          vstprintf(buff, pszString, arg);// ou _vsntprintf() si ta plate-forme la supporte
          OutputDebugString(buff);
          va_end(arg);
       }
       static void print_placebo(LPCTSTR pszString, ...) {}
    };
     
    #ifdef _DEBUG
    #define PRINT print
    #else
    #define PRINT print_placebo
    #endif
     
    #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.

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Puisque tu programmes en C++, pouquoi ne pas faire mieux : abandonner les fonctions à nombre variables d'arguments et opter pour une technique à base de chaînages d'appels (comme les flux standards) ?

    En fait la meilleure solution serait de créer un streambuf utilisant OutputDebugString, et de définir le flux correspondant.

    Voir http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/#flux_entree_sortie

  5. #5
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut
    Tarrke et Médinoc > les deux méthodes que vous proposez fonctionnent mais lorsque je regarde le code ASM généré, il y a toujours un appel à ma fonction print (ceci parce qu'apparement une fonction avec un nombre variable d'arguments ne peut pas être inline - à vérifier tout de même)

    Loulou24 > je débutte en C++ donc j'utilise encore des "vieilles" méthodes du C, je vais jetter un oeil pour les streambuf.

    Merci a tous pour vos réponses ,
    Je vous tiens au courrant.

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si vraiment on veut les performances à tout prix, il ne suffit pas d'appeler une fonction qui ne fait rien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    debugStream << f() << end;
    Ici, même si on s'est débrouillé pour qu'il n'y ait aucune mise en forme et aucun affichage en mode release, le compilateur est quand même obligé d'appeler f (les cas où il peut se rendre compte que c'est inutile et donc optimiser tout seul sont assez rares), ce qui peut avoir un coût.

    Le seul moyen que je connaissaisse d'éviter ça simplement, c'est par une bidouille à base de macros (mais si tu viens du C, ça ne devrait pas te donner trop de boutons) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define LOG if(logDisabled) ; else debugStream 
     
    LOG << "Toto" << endl;
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut
    Heu je viens du C mais on ne peut pas dire que j'avais un niveau très élevé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define LOG if(logDisabled) ; else debugStream
    logDisabled et debugStream correspondent à quoi? (Je suppose que debugStream est un flux mais quel fichier d'entete dois-je inclure?)

    Pour les streamBuff j'ai jetté un oeil mais je vais encore patienter un peu avant d'utiliser çelà (je suis vraiment trop débutant)

    (Sinon ma méthode marche réellement : il n'y a plus d'appel ni de définition de la fonction debug::print() ni de définition dans la section data des chaines de caractères utilisées lors de l'appel de debug::print().)

    Merci d'avance

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Crisanar
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define LOG if(logDisabled) ; else debugStream
    logDisabled et debugStream correspondent à quoi? (Je suppose que debugStream est un flux mais quel fichier d'entete dois-je inclure?)
    debugStream est un flux à contruire toi même, de la manière indiquée par Loulou. logEnabled est un boolée qui te permet de décider si tu dois où non logger un certain type d'info.

    Mon poste n'avais pas pour ambition de fournir une solution clef en main, mais juste de montrer comment on peut optimiser les calculs néccessaires à l'affichage dans le cos où on n'affiche pas.

    Si tu veux du clef en main, tu peux aussi utiliser une bibliothèque existante. Celle sur http://www.torjo.com/ m'a semblé sympa (et elle utilise une macro comme j'ai montré), mais je n'ai pas encore eu l'occasion de l'essayer. Il existe aussi toute une série de bibliothèque de log qui se veulent avoir une interface semblable quel que soit le langage (log4java, log4cpp, log4...), mais elle m'avais semblé un peu lourde.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut
    Salut JolyLoic,
    Je ne voulais pas spécialement une solution clé en main, mais étant plus ou moins débutant, je ne savais si le flux que tu proposais était déja créé ou pas, ni si la variable logDisabled était une variable existante.

    En tout cas merci à tous pour vos réponses, je pense pouvoir essayer de me débrouiller avec celà

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

Discussions similaires

  1. Ne pas appeler une fonction sur un évènement
    Par beegees dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 01/06/2009, 11h32
  2. Appel d'une fonction en mode post
    Par Wilco dans le forum Langage
    Réponses: 2
    Dernier message: 29/05/2009, 19h32
  3. confirm ne me permt pas d'appeler une fonction javascript
    Par beegees dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 18/04/2009, 10h38
  4. Appel d'une fonction en mode bizarre
    Par zarbiman dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 23/11/2007, 14h35
  5. Appeler une fonction avec/sans parenthèses
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 29/12/2002, 18h48

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