Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Astuce pour compilation conditionnelle

20 réponses
Avatar
Michael Moreno
Bonjour,

Je recherche une astuce pour la compilation conditionnelle.

Supposons par exemple que j'ai de nombreuses lignes dans chaque classe
du type :

#if _DEBUG
...
#endif

Si je definis pour chaque classe un _DEBUG_MA_CLASSE alors je perds
l'aspect global du _DEBUG et c'est penible.
Si j'utilise pour chaque classe le meme _DEBUG alors c'est soit tout,
soit rien.

Aussi je me demande si la meilleure solution est de faire quelque chose
du genre dans chaque cpp

#define DEBUG_ON 1

et apres

#if _DEBUG == DEBUG_ON
...
#endif

D'apres vous est-ce la bonne solution a l'usage ou existe-t-il une
solution standard ?

Merci.

--
----
http://michael.moreno.free.fr/

10 réponses

1 2
Avatar
Olivier Azeau
Michael Moreno wrote:
Bonjour,

Je recherche une astuce pour la compilation conditionnelle.

Supposons par exemple que j'ai de nombreuses lignes dans chaque classe
du type :

#if _DEBUG
...
#endif

Si je definis pour chaque classe un _DEBUG_MA_CLASSE alors je perds
l'aspect global du _DEBUG et c'est penible.
Si j'utilise pour chaque classe le meme _DEBUG alors c'est soit tout,
soit rien.

Aussi je me demande si la meilleure solution est de faire quelque chose
du genre dans chaque cpp

#define DEBUG_ON 1

et apres

#if _DEBUG == DEBUG_ON
...
#endif

D'apres vous est-ce la bonne solution a l'usage ou existe-t-il une
solution standard ?

Merci.



Dans le même genre, on a :
#define DEBUG_ON(unit) unit
#define DEBUG_CLASS_A 1
#if DEBUG_ON(DEBUG_CLASS_A)

qui permet de :
- désactiver le debug au niveau d'une classe : #define DEBUG_CLASS_A 0
- désactiver le debug globalement : #define DEBUG_ON(unit) 0
- forcer l'ensemble du debug globalement : #define DEBUG_ON(unit) 1
- définir des niveaux de debug activables séparément :
#define DEBUG_LEVEL1_ON(unit) unit
#define DEBUG_LEVEL2_ON(unit) unit
#define DEBUG_CLASS_A 1
#if DEBUG_LEVEL1_ON(DEBUG_CLASS_A)
#if DEBUG_LEVEL2_ON(DEBUG_CLASS_A)

Pour ma part j'essaie de m'arrêter là car le seul risque quand on
commence à jouer avec les macros c'est qu'on a quelquefois trop tendance
à pousser le bouchon un peu loin...

Genre :
#define DEBUG_ON(unit,level) DEBUG_##level##_ON(unit)
#define DEBUG_LEVEL1_ON(unit) unit
#define DEBUG_CLASS_A 1
#if DEBUG_ON(DEBUG_CLASS_A,LEVEL1)

PS : je ne sais pas si c'est off-topic tout ça (le préprocesseur fait-il
"partie du langage" ?)

Avatar
Michael Moreno
Merci,

PS : je ne sais pas si c'est off-topic tout ça (le préprocesseur fait-il
"partie du langage" ?)


Je me suis pose la question longtemps (2h) avant de poster et j'ai
conclus que je ne connaissais pas un seul forum intitule du genre
"fr.comp.preprocesseur.c++" alors je me suis dit que ca serait
probablement accepte.

--
----
http://michael.moreno.free.fr/

Avatar
Fabien LE LEZ
On Thu, 16 Dec 2004 18:13:03 +0100, Olivier Azeau :

le préprocesseur fait-il
"partie du langage" ?


La partie commune aux préprocesseurs, oui.
Les spécificités de tel ou tel processeur (#pragma), non.


--
;-)

Avatar
James Kanze
Michael Moreno wrote:

Je recherche une astuce pour la compilation conditionnelle.


Tu pratiques l'obfuscation active ?

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
kanze
Olivier Azeau wrote:

[...]
PS : je ne sais pas si c'est off-topic tout ça (le
préprocesseur fait-il "partie du langage" ?)


Tout à fait. Section 16 de la norme, en ce qui concerne les
« directifs ». Quand on parle du préprocesseur, en fait, on
considère en général les six premières phase de traduction,
décrites en §2.1.

Ceci dit, ce n'est pas une raison d'en abuser. Dans la pratique,
c'est rarissime qu'on se sert de la compilation conditionnelle
dans le code bien écrit -- et jamais dans une fonction, comme il
en est question ici. (J'en ai quelques exemples qui trainent
dans le code à ma site, mais seulement dans les en-têtes, au
niveaux de portée du fichier.)

Voir par exemple
http://www.chris-lott.org/resources/cstyle/ifdefs.pdf.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Olivier Azeau
wrote:
Olivier Azeau wrote:

[...]

PS : je ne sais pas si c'est off-topic tout ça (le
préprocesseur fait-il "partie du langage" ?)



Tout à fait. Section 16 de la norme, en ce qui concerne les
« directifs ». Quand on parle du préprocesseur, en fait, on
considère en général les six premières phase de traduction,
décrites en §2.1.

Ceci dit, ce n'est pas une raison d'en abuser. Dans la pratique,
c'est rarissime qu'on se sert de la compilation conditionnelle
dans le code bien écrit -- et jamais dans une fonction, comme il
en est question ici. (J'en ai quelques exemples qui trainent
dans le code à ma site, mais seulement dans les en-têtes, au
niveaux de portée du fichier.)

Voir par exemple
http://www.chris-lott.org/resources/cstyle/ifdefs.pdf.



Je suis d'accord pour proscrire la compilation conditionnelle en dehors
des en-têtes : sans aller jusqu'à une notion de code "bien écrit", il
s'agit surtout (pour moi) d'avoir un code lisible.

Je trouve cependant acceptable de se limiter à la présence de macros
paramètrées à l'intérieur des fonctions car je ne connais aucun idiome
(hors utilisation du pre-processeur) qui permette d'inhiber la
génération de code binaire superflu (en tirant, par exemple, parti des
optimisations du compilateur).

cf par exemple le code de l'article que tu mentionnes :
#ifdef NDEBUG
# define DEBUG(list) /* nothing */
#else
# define DEBUG(list) printf list
#endif
DEBUG(("oops: %s %dn", b, c));

qui devient en C++ :
#ifdef NDEBUG
# define DEBUG(list) /* nothing */
#else
# define DEBUG(list) someDebugOutputStream << list << std::endl
#endif
DEBUG("oops: " << b << c);


Avatar
Michael Moreno
Tu pratiques l'obfuscation active ?


Comment puis-je faire pour debugger sans utiliser la compilation
conditionnelle ?

chez moi ca s'arrete a :
#if_Debug
OutputDebugString("...");
#end if

Je ne veux pas aller plus loin que cela.

--
----
http://michael.moreno.free.fr/

Avatar
Olivier Azeau
Michael Moreno wrote:
Tu pratiques l'obfuscation active ?



Comment puis-je faire pour debugger sans utiliser la compilation
conditionnelle ?

chez moi ca s'arrete a :
#if_Debug
OutputDebugString("...");
#end if

Je ne veux pas aller plus loin que cela.

Dans ce cas, considère peut être qqe chose comme :


#define DEBUG_OUTPUT(data) { std::ostringstream s; s << data << 'n';
OutputDebugString(s.str().c_str()); }

DEBUG_OUTPUT( "..." << x << "..." );

qui est, à mon goût, plus lisible.


Avatar
drkm
Olivier Azeau writes:

Dans ce cas, considère peut être qqe chose comme :

#define DEBUG_OUTPUT(data) { std::ostringstream s; s << data << 'n';
OutputDebugString(s.str().c_str()); }

DEBUG_OUTPUT( "..." << x << "..." );

qui est, à mon goût, plus lisible.


Je n'ai jamais trouvé très lisible l'utilisation d'opérateurs de
flux (ou de décalage) en argument d'une macro ou d'une fonction. Et
que dire de :

DEBUG_OUTPUT( "..." << s << "..." ) ;

Pourquoi ne pas utiliser une bibliothèque dédiée, comme log4cxx ?

--drkm

Avatar
Falk Tannhäuser
Olivier Azeau wrote:

#define DEBUG_OUTPUT(data) { std::ostringstream s; s << data << 'n';
OutputDebugString(s.str().c_str()); }

DEBUG_OUTPUT( "..." << x << "..." );


Je préfère quelque chose comme

#define DEBUG_OUTPUT(data) do {
std::ostringstream s;
s << data << 'n';
OutputDebugString(s.str().c_str());
} while(false)

afin d'éviter des problèmes dans

if(gnagnagna)
DEBUG_OUTPUT("super: " << aaa*6.55957);
else
DEBUG_OUTPUT("cool: " << bb*1.95583 << ' ' << c*40.3399);

(qui risque de compiler sans broncher, en donnant un mauvais
résultat, s'il est imbriqué dans un autre 'if').


Par contre, un avantage non négligeable d'un macro est de
permettre l'utilisation des macros prédéfinis comme __FILE__
et __LINE__ et de l'opérateur #.

Falk

1 2