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 :

Trace arguments erreur


Sujet :

C++

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

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Points : 58
    Points
    58
    Par défaut Trace arguments erreur
    Bonjour,

    Pour pouvoir garder des traces dans mon application, j'ai mis au point un singleton TraceManager. La logique tourne autour de la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACE(fmt, ...) TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt, __VA_ARGS__)
    Ainsi, je peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TRACE("valeur de i : %d", i); // i variable connue
    Sous Visual Studio 2010, j'arrive également à tracer sans argument comme :

    Par contre, lorsque j'essaie de tracer sans argument sous QtCreator, j'obtiens l'erreur suivante (la ligne considérée correspond à celle où TRACE est appelée) :

    erreur : expected primary-expression before ')' token
    L'erreur peut être évitée avec mais c'est pas très pratique..

    Une idée ?

    Merci

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Mais pourquoi le ; te paraît-il "superflu dans un cas et pas dans l'autre? Sinon, pourquoi ne pas l'intégrer à la macro?
    Oops, lu trop vite, répondu trop vite, grillé par leternel dans ma réponse-rectif

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Peut-être un gros #define TRACELINE(msg) quelque choseAvec éventuellement une fonction dédiée, telle que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TraceManager::Trace(__FUNCTION__, __FILE__, __LINE__, msg)
    autre solution, une fonction inline ou dans une lib.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline void trace(const char* fmt, ...) {
        va_list args;
        va_start(args);
        TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt, args);
        va_end(args);
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Simple supposition mais rajouter un ";" a la fin ça ferais pas l'affaire?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACE(fmt, ...) TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt, __VA_ARGS__);
    Homer J. Simpson


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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par Astraya Voir le message
    Simple supposition mais rajouter un ";" a la fin ça ferais pas l'affaire?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACE(fmt, ...) TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt, __VA_ARGS__);
    Oui, mais non...

    L'habitude quand on travaille avec des macros, consiste à ne justement pas rajouter de ";" à la fin, pour laisser l'utilisateur seul juge du moment où il le place.

    Le fait est qu'une macro va simplement définir un symbole comme l'équivalent du code qui le défini et que ce symbole sera purement et simplement remplacé par son contenu lorsque le préprocesseur va passer par là.

    Seulement, on n'a jamais la moindre certitude de la manière (peut etre erronée, mais pas forcément) dont la macro pourrait être utilisée, et on pourrait très bien avoir un code (tout à fait juste au demeurant) proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foo( TRACE("valeur de i: %d",i),somethingElse);
    parce que foo prendrait, en l'occurrence, un pointeur de fonction comme premier argument

    Si tu places le point virgule directement dans la macro, un tel appel devient totalement illégal, et le compilateur se plaindra d'avoir un "somethingElse" qui n'a pas à se trouver là (en plus de se plaindre de ne pas avoir de correspondance avec foo(/* pointeur de fonction*/) )

    Bref, non: on ne place pas de ";" en fin de macro
    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

  6. #6
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Il y a eu toute une histoire de point virgule, mais n'est-ce pas juste un oublie du PO ?

    Sinon, j'imagine que la macro avec un seul paramètre donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt, )
    Et comme la parenthèse suit la virgule, il y a une erreur de syntaxe.

    Un moyen serait de tout mettre en variadic (#define TRACE(...)), mais on perd le nom du paramètre.

    Une autre solution serait de compter le nombre de paramètre dans __VA_ARGS__ et ajouter une virgule si différent de 0.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define TRACE(fmt, ...) TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt \
      BOOST_PP_IF( \
        PP_VARIADIC_SIZE(__VA_ARGS__),  \
        BOOST_PP_COMMA, \
        BOOST_PP_EMPTY \
      )() \
      __VA_ARGS__)
    La macro PP_VARIADIC_SIZE retournant le nombre de paramètre.
    Je n'ai pas réussi à le faire avec seulement boost preprocessor, c'est peut-être possible mais j'ai une macro qui se comporte comme tel ici (C'est juste monstrueux )

  7. #7
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    @ Koala:
    Voila pourquoi je n'aime pas, je hais, j’exècre les macros et essaye d'en supprimer le plus possible :p

    Ce que je recommanderais pour limiter la casse: une macro pour juste get ton singleton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACEMANAGER TraceManager::GetInstance()
    et ensuite tu utilises ta fonction comme-t-elle
    Homer J. Simpson


  8. #8
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    @Astraya: Il faut quand même faire appel au 'macro magique' sinon __FUNCTION__, __LINE__ et __FILE__ feront référence à la fonction de formatage et non à l'emplacement de la macro.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACE TraceManager::GetInstance()->trace(__FUNCTION__, __FILE__, __LINE__).format
    Par contre, j'ai trouver un truc sympa pour ajouter une virgule si __VA_ARGS__ n'est pas vide: concaténation (##)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TRACE(fmt, ...) TraceManager::GetInstance()->Trace(__FUNCTION__, __FILE__, __LINE__, fmt,## __VA_ARGS__)

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

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Points : 58
    Points
    58
    Par défaut
    Merci à tous pour vos réponses

    Bref, non: on ne place pas de ";" en fin de macro
    C'est ce que je me disais. Après effectivement, dans le main pour mes tests, quand j'appelle la macro TRACE("Test"), j'ai oublié de mettre clairement le ";" mais ce n'est pas le problème.

    Par contre, j'ai trouver un truc sympa pour ajouter une virgule si __VA_ARGS__ n'est pas vide: concaténation (##)
    Pas mal comme solution, ça semble fonctionner!

    Merci encore

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

Discussions similaires

  1. Où trouver la trace des erreurs dans Sharepoint
    Par ml_hamdi dans le forum Configuration
    Réponses: 9
    Dernier message: 30/09/2009, 20h48
  2. Où trouver la trace des erreurs dans Sharepoint
    Par ml_hamdi dans le forum SharePoint
    Réponses: 9
    Dernier message: 30/09/2009, 20h48
  3. Réponses: 6
    Dernier message: 20/01/2006, 18h42
  4. Trace des erreurs Oracle 8i
    Par Endymion222 dans le forum Oracle
    Réponses: 17
    Dernier message: 08/11/2005, 11h40
  5. Réponses: 3
    Dernier message: 30/09/2004, 20h16

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