GCC supprime du code à mon insu !?

GCC supprime du code à mon insu !? - C++ - Programmation

Marsh Posté le 13-05-2010 à 15:15:41    

Bonjour à tous,
 
Derrière ce titre un peu racoleur ce cache un problème assez amusant (ou pas, ça dépend du point de vue).
 
J'ai une classe qui ressemble à ça :
 

Code :
  1. class QtLogger : public Logger
  2. {
  3. public:
  4.    static const QtLogger me;
  5. private:
  6.    QtLogger();
  7. };


 
L'idée c'est d'avoir un logger spécifique à Qt qui va catcher les messages de Qt et les "logger" quelque part.
Voici l'implémentation (j'ai un peu simplifié) :
 

Code :
  1. void handler(QtMsgType type, const char* msg)
  2. {
  3.    QtLogger::me.log(msg);
  4. }
  5. const QtLogger QtLogger::me;
  6. QtLogger::QtLogger() :
  7.    Logger("Qt" )
  8. {
  9.    qInstallMsgHandler(handler); // Fonction fournit par Qt permettant d'attraper ses messages via un handler.
  10. }


 
Or, le constructeur de QtLogger n'est jamais appelé ! À mon avis GCC doit shooter la variable me en se disant qu'elle n'est jamais utilisée. Si j'appelle artificiellement QtLogger::me.log(..) quelque part au hasard dans mon code alors le constructeur est appelé correctement.
 
Quelqu'un aurait une idée !? Est-ce une comportement normal ?

Reply

Marsh Posté le 13-05-2010 à 15:15:41   

Reply

Marsh Posté le 13-05-2010 à 15:27:11    

Je parie que tu as mis le fichier objet généré dans une bibliothèque statique?
 
Si c'est bien le cas, le problème est que tu n'as pas compris comment les bibliothèques statiques fonctionnent: l'éditeur de liens extrait de celles-ci les objets fournissant des symboles n'ayant pas de définition au moment où la bibliothèque est examinée.  Comme ce n'est pas le cas -- tu désires que tout fonctionne par effet de bord de l'initialisation -- le fichier n'est pas extrait.  Quand tu ajoutes une référence artificielle, l'éditeur de liens a une raison d'extraire le fichier objet.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 13-05-2010 à 15:42:13    

Hello, merci pour ta réponse, effectivement j'utilise ce code dans un bibliothèque statique. Je vais me renseigner sur le sujet, ne m'étant jamais vraiment intéressé au processus derrière l'édition de liens.
 
Existe-il une solution à mon problème ou dois-je revoir mon approche ?


Message édité par Ummon le 13-05-2010 à 15:42:23
Reply

Marsh Posté le 13-05-2010 à 16:13:02    

stocke un shared_ptr sur ton logger et lors du premier appel de log(), test si il est construit ou pas. Le cas echeant , construit le dynamiquement.

Reply

Marsh Posté le 13-05-2010 à 16:24:39    

Joel F a écrit :

stocke un shared_ptr sur ton logger et lors du premier appel de log(), test si il est construit ou pas. Le cas echeant , construit le dynamiquement.


Oui mais dans mon cas 'log' n'est appelé quand dans le cas où un objet QtLogger a été construit puisque c'est à ce moment là qu'est posé le handler. Je crois que je vais déplacer 'static const QtLogger me' dans une autre unité de compilation... c'est un peu zarb.

Reply

Marsh Posté le 13-05-2010 à 16:44:11    

Il y a différentes solutions:
- ne pas mettre le code dans une bibliothèque statique
   - le mettre dans une bibliothèque dynamique
   - mettre le fichier objet réalisant l'enregistrement directement sur la ligne de link
- référencer l'objet
   - par un appel à une fonction factice ou réalisant l'enregistrement dans main
   - en jouant sur les options de l'éditeur de liens (--undefined avec l'éditeur de liens de GNU)


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 13-05-2010 à 17:25:45    

deja, moi, les static globales dans des lib :/
je comprends pas pourquoi tt le monde pense que le logger doit etre global vv

Reply

Marsh Posté le 13-05-2010 à 18:14:00    

Joel F a écrit :

je comprends pas pourquoi tt le monde pense que le logger doit etre global vv


 
Je crois que tu donnes la réponse dans ta question.  Si tu penses au logger plutôt qu'à un logger, c'est normal qu'il soit global.
 
D'après mon expérience, c'est quand même mieux que la situation où on a partiellement prévu d'en avoir plusieurs mais en pratique il n'y en a qu'un et le code suppose que les différents manière possible d'accéder à un logger sont équivalentes.  Dans le premier cas, on peut planifier le changement, dans le second, on vit l'illusion qu'il sera plus facile que dans le premier alors que si c'est vrai, c'est marginal et par hasard.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 13-05-2010 à 18:37:48    

bah dans ttes mes applis, j'ai une collection de loggeur ou je veux changer dynamiquement ou ca part (ficheir, console) en fonction du composant logger, de l'algo etc.
 
en gros j'ai des log(message,logging_sink);
 

Reply

Marsh Posté le 13-05-2010 à 20:33:19    

J'ai pas dit que j'approuvais le raisonnement, simplement je le comprends.
 
Tout comme je comprends le raisonnement dans le cas présent -- qui n'est pas tant lié aux logs qu'à l'enregistrement automatique de certaines instances -- mais ne l'approuve pas.  Mon expérience me dit que se fier à ces enregistrements entraîne des problèmes d'ordre et de dépendances subtiles.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 13-05-2010 à 20:33:19   

Reply

Marsh Posté le 13-05-2010 à 22:35:13    

ok ^^

Reply

Marsh Posté le 14-05-2010 à 03:22:02    

Merci pour vos commentaires, j'ai choisi la méthode de l'appel à une méthode factice.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed