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 :

[PREPROCESSEUR] quelle difference ??


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut [PREPROCESSEUR] quelle difference ??
    salut j'ai une simple (encore une) question
    si j'ecris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define LOG 0
     
    #if LOG
    #define _LOG(text,params) STLOG_WRITE(text,params)
    #else
    #define _LOG(text,params)
    #endif
    je peu choisir si je log ou pas certaines chose, si je met
    #define LOG 1 ça trace
    #define LOG0 ça trace pas

    Mais il me vient une question dans le cas LOG = 0
    le compilo met quoi a la place de ma macro _LOG(text,params) ???

    En cherchant j'ai trouver des gens qui faisaient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #define LOG 0
     
    #if LOG
    #define _LOG(text,params) STLOG_WRITE(text,params)
    #else
    #define _LOG(text,params) /
    inline doNothin(){}
    #endif
    Ma question est : quel est le plus propre et bein sur le plus "stable" il me sembke quand meme que la solution inline donne l'assurance d'avoir quelque chose dans les deux cas !!
    Mais f(){} c'est compilé, linké et présent dans l'exe ???
    le compilo fait le menage non ? alors quel interet de mettre une fonction inline dans ce cas ??

  2. #2
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Salut,

    Dans le même genre, j'avais trouvé sur un site du genre GameDev une version des outils de debug type MFC pour insérer dans un projet non-MFC, et ça donnait ç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
    #ifndef __DEBUG_H__
    #define __DEBUG_H__
     
    #ifdef _DEBUG
     
    	#define ASSERT(x) { if (!(x)) _asm{int 0x03} }
    	#define VERIFY(x)  { if (!(x)) _asm{int 0x03} }
     
    	void _trace(char *fmt, ...);
    	#define TRACE _trace
     
    #else
     
    	#define ASSERT(x)
    	#define VERIFY(x) x
     
    	inline void _trace(char* fmt, ...) { }
    	#define TRACE  1 ? (void)0 : _trace
     
    #endif
     
    #endif // __DEBUG_H__
    (sachant que void _trace(char *fmt, ...); est défini dans le .cpp correspondant bien sûr...)

    Ma question est la même je pense, à quoi sert:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	inline void _trace(char* fmt, ...) { }
    	#define TRACE  1 ? (void)0 : _trace
    est ce que, comme pour ASSERT un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define TRACE(x)
    ou encore
    inline void TRACE(char* fmt, ...) { }
    n'aurait pas suffi ?

    Voilà voilà, ça m'intrigue aussi cette histoire

  3. #3
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    le compilo met quoi a la place de ma macro _LOG(text,params) ???
    Absolument rien.

    Mais f(){} c'est compilé, linké et présent dans l'exe ???
    le compilo fait le menage non ? alors quel interet de mettre une fonction inline dans ce cas ??
    Avec un minimum d'optimisations, je pense que le ocmpilo fait effectivement le ménage. En ce qui concerne ton code, il est truffé de fautes et le principe en lui-même est douteux. Si tu l'as trouvé tel quel alors il n'a jamais été testé, sinon donne le vrai.

    est ce que, comme pour ASSERT un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define TRACE(x)
    ou encore
    inline void TRACE(char* fmt, ...){}
    n'aurait pas suffi ?
    Non, car cette macro ne prend pas de paramètres. En fait elle ne pourrait pas, car il y a utilisation de l'ellipse (...) pour spécifier un nombre variable d'arguments. Or, il n'existe aucun moyen de construire une macro à arguments variables.

    En gros cela donnerait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Code original
    TRACE("Salut %s", "Bob");
     
    // En debug
    _trace("Salut %s", "Bob");
     
    // En release
    _trace("Salut %s", "Bob"); // mais _trace est vide - ce sera viré par le compilo
     
    // Ton idée
    ("Salut %s", "Bob"); // ça compilera pas beaucoup :)
    Un autre cas dans lequel il faut définir une fonction inline, c'est lorsqu'on doit évaluer le paramètre de la macro quoiqu'il arrive

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert(fichier.open("toto.txt"));
    Si on remplace assert par que dalle en mode release, le fichier ne sera pas ouvert.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut
    Mais f(){} c'est compilé, linké et présent dans l'exe ???
    le compilo fait le menage non ? alors quel interet de mettre une fonction inline dans ce cas ??
    Avec un minimum d'optimisations, je pense que le ocmpilo fait effectivement le ménage. En ce qui concerne ton code, il est truffé de fautes et le principe en lui-même est douteux. Si tu l'as trouvé tel quel alors il n'a jamais été testé, sinon donne le vrai.
    voici le vrai code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #ifdef STLOG_PRINT_COMPILE_INFO
    	#define STLOG_EXPAND_INFO(file, line) \
    		CURRENT_FILE = file;	CURRENT_LINE=line;
    	#else
    		inline void _______DoNothing0() {};
    		#define STLOG_EXPAND_INFO(file, line) \
    			1 ? void(0) : _______DoNothing0();
    	#endif
    c'est chian a lire c'est pour ça que j'ai mi un vague apperçu desolé
    Mais le pourquoi rest e obscure quand meme....
    je vais rester avec ma premiere idee si le compilo met rien ça me va

    EDIT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define LOG 0 
     
    #if LOG 
    #define _LOG(text,params) STLOG_WRITE(text,params) 
    #else 
    #define _LOG(text,params) 
    #endif
    ya quelque chose qui te derange la dedans ???

  5. #5
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Si on remplace assert par que dalle en mode release, le fichier ne sera pas ouvert.
    OK, donc j'imagine que c'est pour ça qu'ils ont fait le VERIFY en plus du ASSERT ...

    Par contre, il y a un truc que je ne comprends toujours pas

    Non, car cette macro ne prend pas de paramètres. En fait elle ne pourrait pas, car il y a utilisation de l'ellipse (...) pour spécifier un nombre variable d'arguments. Or, il n'existe aucun moyen de construire une macro à arguments variables.
    ça c'est bon, finalement ça parait plutôt clair et évident une fois que tu l'as dit

    Mais pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     inline void _trace(char* fmt, ...) { }
       #define TRACE  1 ? (void)0 : _trace
    au lieu du simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inline void TRACE(char* fmt, ...) { }
    Est-ce qu'il y a une autre subtilité ?

  6. #6
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define LOG 0
     
    #if LOG
    #define _LOG(text,params) STLOG_WRITE(text,params)
    #else
    #define _LOG(text,params)
    #endif
    ya quelque chose qui te derange la dedans ???
    En fait après reflexion, je pense que c'est une mauvaise idée de ne rien mettre. Imagine cette instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _LOG(x, y), _LOG(a, b);
    C'est un peu n'importe quoi mais c'est valide. Et ce n'est sûrement pas le seul cas problèmatique.
    Question à trois francs : sous quelle forme se présente le paramètre params ?

    Mais pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     inline void _trace(char* fmt, ...) { }
       #define TRACE  1 ? (void)0 : _trace
    au lieu du simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inline void TRACE(char* fmt, ...) { }
    Est-ce qu'il y a une autre subtilité ?
    A priori non, mais j'imagine qu'il y en a tout de même une.

    Par contre ce qui me choque, c'est tous ces opérateurs ternaires. Si quelqu'un a une explication...

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut reponse a deux balles
    c'est une entre d'ellipse....
    je sais c'est mal mais c'est du log style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _LOG(TEXT("mon %d log"),1));
    C'est tres pourri masi je voulais une macro qui puisse faire sauter les log facilement...
    Si tu as une meilleur façon je suis preneur en fait !

  8. #8
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    J'ai du mal à voir comment tu fais passer un nombre variable de paramètres dans un seul paramètre de ta macro ?

    A l'époque je faisais comme vu plus haut : une macro sans paramètre qui remplace juste le nom de la fonction. C'est moche, mais ma foi...

    Le mieux est encore d'utiliser un logging style flux C++, avec opérateur <<.

  9. #9
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    En ce moment, j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    LOG("Texte ")(hopUnInt)(" et aussi ")(hopUneString)
        (/*hop une cst*/42)(" et this pour finir: ")(this->toString())
        .trace("balise pour le fichier de log")
        .alarm(niveau_de_criticite) // pour un composant qui 
                          // centralise les alarmes
        .exception<type_exception>() // si nécessaire
        ;
    La syntaxe est certes un peu zarbi, mais au moins je n'ai aucun risque de me planter dans les formats, le texte est généré une fois pour toutes et redispatché ensuite à diverses fonctions.

    Je suis parti de SMART_ASSERT présenté dans un article d'Andrei Alexandrescu qui est dispo sur le site du C/C++ Users Journal.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut poua
    Citation Envoyé par Luc Hermitte
    En ce moment, j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    LOG("Texte ")(hopUnInt)(" et aussi ")(hopUneString)
        (/*hop une cst*/42)(" et this pour finir: ")(this->toString())
        .trace("balise pour le fichier de log")
        .alarm(niveau_de_criticite) // pour un composant qui 
                          // centralise les alarmes
        .exception<type_exception>() // si nécessaire
        ;
    La syntaxe est certes un peu zarbi, mais au moins je n'ai aucun risque de me planter dans les formats, le texte est généré une fois pour toutes et redispatché ensuite à diverses fonctions.

    Je suis parti de SMART_ASSERT présenté dans un article d'Andrei Alexandrescu qui est dispo sur le site du C/C++ Users Journal.
    waouuu paye ton truc !!! je suppose que ça marche je vasi essayer de voir coment ça marche.... merci les gars

    EDIT : C'est bon pour moi sur le sujet mais comme il y a d'autres question je la passe pas en [resolu] j'attends l'avis de bigquick

  11. #11
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Pour moi c'est presque bon

    La solution de Luc à l'air super complète, mais euh, voici le lien en question (ou un lien qui s'en rapproche en tout cas): http://www.cuj.com/documents/s=8464/...p0308alexandr/ ... c'est assez tendu Ca devrait plaire à Loulou24 je pense (merci au passage pour tes tutoriaux sur la meta-programmation, j'essaye de comprendre tout ça petit à petit!)

    Enfin donc n'ai pas trop compris comment ça fonctionne pour qu'en release le code compile tranquillement... En tout cas, ça à l'air bien compliqué de faire une belle classe de logs / trace / gestion d'erreur ....

    ps: sinon toujours pas d'explication pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define TRACE  1 ? (void)0 : _trace
    #define STLOG_EXPAND_INFO(file, line)  1 ? void(0) : _DoNothing0();
    mais bon, ça fonctionne, alors tant pis pour les subtilités

  12. #12
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Citation Envoyé par bigquick
    En tout cas, ça à l'air bien compliqué de faire une belle classe de logs / trace / gestion d'erreur ....
    La dernière fois que j'avais vérifié, ils n'avaient toujours pas convergé chez boost. Même si le besoin avait été bel et bien ressenti et étudié.
    Bref, le beau truc ultime n'est pas évident.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

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

Discussions similaires

  1. URL/URI quelles différences ?
    Par Kylen dans le forum Général Conception Web
    Réponses: 8
    Dernier message: 03/02/2015, 20h09
  2. Quelles Differences entre UML et Merise?
    Par hugobob dans le forum Méthodes
    Réponses: 6
    Dernier message: 13/03/2013, 12h05
  3. Réponses: 3
    Dernier message: 02/04/2006, 19h38
  4. Réponses: 3
    Dernier message: 16/01/2006, 10h29
  5. [Nombre Champs][MaxCount]Quelles differences selon les SGBD?
    Par netomin dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 24/12/2005, 22h30

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