La plupart de mes classes ont des variables de débogage, et cela les rend souvent ressemblant à ceci: et méthodes peut ressembler à ceci: p> Peu de choses sont plus laids que tous ceux #Ifndef Ndebug. Malheureusement, aucun compilateur que je connais peut optimiser la variable vérifier em> sans ces #Ifndefs (je ne sais pas si cela est même autorisé). P> J'ai donc essayé de trouver une solution qui ferait ma vie plus facile. Voici comment cela semble maintenant: p> donc en mode de débogage, débogue_var (t) fait simplement une t. Sinon, il fait une "classe null" avec des non-ops. Et mon code ressemblerait à ceci: p> puis je pourrais simplement utiliser vérifier em> comme s'il s'agissait d'une variable normale! Impressionnant! Cependant, il reste encore 2 problèmes que je ne peux pas être résolu: p> la "classe null" n'a pas de push_back (), etc. Pas de biggie. La plupart des variables de débogage sont de toute façon intenses. P> Chaque classe de C ++ est d'au moins 1 charpente. Donc, même en mode de libération, une classe qui utilise n debug Vars sera au moins N caractères trop gros. Ceci est dans mes yeux juste inacceptable. C'est contre le principe de surcharge zéro que je vise autant que possible. P> donc,
4 Réponses :
quelque chose comme ça pourrait fonctionner: Exemple d'utilisation: p> Toutefois, veuillez noter qu'en général, les différences sont plus différentes. En termes de mise en page de la mémoire entre différentes configurations de votre programme, les bugs plus difficiles («Ça fonctionne dans le débogage, mais se bloque au hasard») Vous allez obtenir. Donc, si vous vous trouvez souvent en utilisant des données de débogage supplémentaires, vous devez redéfinir vos structures de données. Lorsqu'il y a beaucoup de données de débogage, préférez laisser un pointeur pour déboguer des données en mode de libération (c.-à-d. struct foo {...; struct Foodebug * débogdata; / * null en version * /}; code>) }; / p> p>
Eh bien, débog_var_op est juste une forme plus courte de #Ifndef Ndebug. Je pourrais en fait l'utiliser, cependant, parce que cela ne gâcherait pas mon indentant comme #Ifndef.
Yup, le seul avantage est que c'est une doublure.
+1 Je préférerais de loin cette solution à la réponse acceptée. Bien sûr, ce n'est pas aussi élégant et «moderne C ++ - ISH», mais il présente plusieurs avantages. Tout d'abord, cela résout également le problème 1) de l'OP. Deuxièmement, cela montre clairement à tous ceux qui lisent le code que tout ce qui est à l'intérieur debug_var_op n'est exécuté que dans le mode de débogage.
BTW: Je pense enlever le; Après le code dans la définition de la macro debug_var_op pour forcer l'utilisateur de la macro à l'alimenter. Fonctionne généralement mieux avec des outils qui tentent de formater votre code source. Peut-être envelopper la chose en tout dans un "code de code;} tandis que (0)".
Vous ne pouvez pas corriger le 2e problème, car la norme C ++ nécessite que la taille d'une classe ou un objet soit au moins un octet. P>
La solution la plus simple ne serait pas d'introduire de tels hacks et de tester correctement votre code. P>
Par la même logique, les affirmations sont des hacks - vous devriez bien tester votre code ... non?
@ZeXSCG, affirmant sur des choses qui sont importantes pour la logique commerciale est bonne. Introduire de nouvelles variables de test uniquement pour que vous puissiez affirmer sur eux est mauvais. C'est une différence subtile, mais importante
@Glen, parfois, il existe certaines hypothèses complexes que vous avez besoin de données supplémentaires pour vérifier. À d'autres moments, les données de débogage consistent à faciliter le débogage - par exemple, les noms d'objet qui sont redondants en libération, mais très utiles tout en débogage.
+1, mais le deuxième problème a une solution sous la forme d'une "optimisation de la classe de base vide": déplacez simplement vos variables de débogage en une classe de base et utilisez (multiple) héritage. Si la dernière classe de base est vide, elle peut être optimisée. C'est un bon endroit pour rappeler toujours à utiliser static_cast CODE> et non de Caux de style C en présence de multiples héritage.
@Alexandre: Comment associeriez-vous un identifiant comme vérifier code> avec chaque classe de base vide?
@Aschepler: contrôleur de structure {#Ifdef ndebug int check; #endif}; code>
Classe A: Checker {...} code>
@Alexandre: Ensuite, en mode de sortie, code comme check + = 1; code> ne compilera pas du tout. @ MIGI'S
NULLCLASS CODE> Le hack permet à ce code de compiler en mode de libération mais ne faites rien, puisqu'il appelle une fonction en ligne vide.
@ASCHEPLER: Tu as raison :). Mon point ne faisait que parler de l'optimisation de la classe de base vide.
Que diriez-vous:
#ifndef NDEBUG #define DEBUG_VAR(T) static nullclass<T> #endif
Je ne savais pas que la solution serait aussi simple. Comme Martin Stone mentionne, vous devez toujours en définir une instance quelque part, mais c'est juste une nuisance mineure.
@ASCHEPLER CODE>: Qu'en est-il de si ce débogage var est requis par objet, pas par classe? Ouais, j'ai vu l'exemple, mais la question n'est-elle pas plus large? Ma recommentation personnelle est de lire
@vjo code> réponse et
@Alexandre c. Code> Commentaire
@Andy T Non, la partie génie de cette solution est que l'instance NullClass peut être statique car elle ne fait que non-OPS. L'instance T normale (en mode de débogage) est toujours non statique.
Que diriez-vous de déclarer l'objet membre statique en mode débogage:
#define DEBUG_VAR(T) static nullclass<T>
Bienvenue pour! Mes compliments sur une première question très bien formée et intéressante: D
Vous devez ajouter un préfixe de débogage au nom de ces variable (par exemple,
Débogou _ code> ou court
dbg _ code>) ou vous ne pourrez pas dire quelle variable est une variable de débogage et qui n'est pas Lorsque vous consultez le fichier source, maintenant que vous n'avez plus
#Ifndef ndebug code> lignes.
Avoir différentes mises en page d'objet dans le mode de débogage / libération est un débutant difficile en attente d'attente. Je trouve de bonnes pratiques pour garder les contrôles de débogage et affirmer en mode de libération et les désactiver après le profilage et le débogage complet. Si votre mode de libération diffère de votre mode de débogage uniquement dans les paramètres d'optimisation, tout ira bien. Prenez particulièrement soin du pesky _secure_scl et _has_iterator_debugging dans Visual Studio, je désactive toujours les deux à moins que j'en ai vraiment besoin.