OVH Cloud OVH Cloud

Question d'elegance

20 réponses
Avatar
Dominique Vaufreydaz
Bonjour,

je définis une fonction qui doit en fonction d'une define de compilation
fait rien ou qqchose genre :

#ifdef DOIT_TRAVAILLER
inline void Travail(char * format, ...)
{
// Tout le toutim
}
#else
inline void Travail(char * format, ...)
{
}
#endif

Ca marche a un detail pret.
si DOIT_TRAVAILLER n'est pas définis
et que j'appelle

Travail( "%d\n", MaFonctionQuiFaitUnCalcul() );

Meme si rien n'est produit a l'ecran, la fonction qui fait le calcul
est appelée et travail pour rien. J'aimerais coder une sorte
de assert dependant de mon define.

QQun a une idée ? Doms.

10 réponses

1 2
Avatar
Franck Branjonneau
"Dominique Vaufreydaz" écrivait:

Bonjour,


Bonjour,

inline void Travail(char * format, ...)


Une fonction inline avec ellipsis ?

--
Franck Branjonneau

Avatar
Laurent Deniau
Mais si la macro n'a pas de parametres (cf mon autre post)


Quel rapport?


Eh bien, on peut ecrire

TRAVAIL("%d_n", calcul());

ou TRAVAIl est une macro, et les parametres ne sont evalues que
si DOIT_TRAVAILLER est definie, et il n'y a pas de double parentheses.


Non, par contre il y a une infame bidouille avec une if-else cache qui
posera pleins de problemes...

Entre tapez

TRAVAIL("%d_n", calcul());

Et

Travail(("%d_n", calcul()));

je ne vois pas une grosse difference et ca a le merite d'etre "plus
propre"...

Au passage, si tu n'as pas devine la definition de Travail:

#ifdef DOIT_TRAVAILLER
#define Travail(afaire) Travail afaire
#else
#define Travail(afaire)
#endif

a+,ld.



Avatar
Michel Decima
Laurent Deniau wrote:
Mais si la macro n'a pas de parametres (cf mon autre post)
Quel rapport?

Eh bien, on peut ecrire


TRAVAIL("%d_n", calcul());

ou TRAVAIl est une macro, et les parametres ne sont evalues que
si DOIT_TRAVAILLER est definie, et il n'y a pas de double parentheses.


Non, par contre il y a une infame bidouille avec une if-else cache qui
posera pleins de problemes...


J'endosse la pleine responsabilité de l'infame bidouille, mais bon,
quand on veut court-circuiter l'appel d'une fonction en éliminant
l'evaluation des paramètres je pense qu'on est deja dans le domaine
de la bidouille (a cause du pre-processeur). Apres, il faut voir ce
qu'on qualifie d'infame, mais je reconnais que ta solution est plus
propre.

A propos des problemes du if-else, tu as des exemples ? Je n'en n'ai pas
encore rencontré, et j'aimerais prevoir le coup avant que ca n'arrive ;)


Entre tapez

TRAVAIL("%d_n", calcul());

Et

Travail(("%d_n", calcul()));

je ne vois pas une grosse difference et ca a le merite d'etre "plus
propre"...


Ca depend. Si on est au debut du projet, je prefere la deuxieme
solution, par contre s'il y a deja une grande quantite de code qui
"travaille", alors je prefere la premiere parce que je n'aurais pas
a propager les doubles parentheses partout ou cela est necessaire.


Au passage, si tu n'as pas devine la definition de Travail:

#ifdef DOIT_TRAVAILLER
#define Travail(afaire) Travail afaire
#else
#define Travail(afaire)
#endif


J'avais devine ;)




Avatar
Franck Branjonneau
"Dominique Vaufreydaz" écrivait:

#ifdef DOIT_TRAVAILLER
# define TRAVAIL_FLAG 1
#else
# define TRAVAIL_FLAG 0
#endif

#define TRAVAIL if (TRAVAIL_FLAG) Travail


Michel disait :

Il y a une methode classique qui consiste a placer l'appel de la
fonction dans l'alternative d'un if


Ne pas négliger ses classiques :

#undef DOIT_TRAVAILLER
TRAVAIL(""); else std::cout << "Goto Hell!!!n";

--
Franck Branjonneau

Avatar
Laurent Deniau

Laurent Deniau wrote:
Mais si la macro n'a pas de parametres (cf mon autre post)
Quel rapport?

Eh bien, on peut ecrire


TRAVAIL("%d_n", calcul());

ou TRAVAIl est une macro, et les parametres ne sont evalues que
si DOIT_TRAVAILLER est definie, et il n'y a pas de double parentheses.


Non, par contre il y a une infame bidouille avec une if-else cache qui
posera pleins de problemes...


J'endosse la pleine responsabilité de l'infame bidouille, mais bon,
quand on veut court-circuiter l'appel d'une fonction en éliminant
l'evaluation des paramètres je pense qu'on est deja dans le domaine
de la bidouille (a cause du pre-processeur). Apres, il faut voir ce
qu'on qualifie d'infame, mais je reconnais que ta solution est plus
propre.

A propos des problemes du if-else, tu as des exemples ? Je n'en n'ai pas
encore rencontré, et j'aimerais prevoir le coup avant que ca n'arrive ;)


C'est que tu n'as pas du utiliser ta macro tres souvent ;-)

if (cond)
TRAVAIL("%dn", MaFonctionQuiFaitUnCalcul() );

il y a une ambiguite sur le else et oblige a ecrire

if (cond) {
TRAVAIL("%dn", MaFonctionQuiFaitUnCalcul() );
}


Entre tapez

TRAVAIL("%d_n", calcul());

Et

Travail(("%d_n", calcul()));

je ne vois pas une grosse difference et ca a le merite d'etre "plus
propre"...


Ca depend. Si on est au debut du projet, je prefere la deuxieme
solution, par contre s'il y a deja une grande quantite de code qui
"travaille", alors je prefere la premiere parce que je n'aurais pas
a propager les doubles parentheses partout ou cela est necessaire.


Par contre il faudra changer tous les Travail en TRAVAIL...

Si je devais eventuellement adapter ta macro, j'irais plutot dans la
direction de

#define Travail !(DOIT_TRAVAILLER) ? (void)0 : Travail

ou plutot que de seulement definir DOIT_TRAVAILLER, on lui donne les
valeurs 0 ou 1. De toute facon pas besoin d'un flag supplementaire.

Cela peut marcher (je n'ai pas de contre exemple en tete) parce que
Travail ne renvoie rien, il devrait donc pas y avoir de cas ou la
precedence de ?: soit ambigue/plus faible.

a+, ld.





Avatar
Michel Decima
Laurent Deniau wrote:

A propos des problemes du if-else, tu as des exemples ? Je n'en n'ai pas
encore rencontré, et j'aimerais prevoir le coup avant que ca n'arrive ;)


C'est que tu n'as pas du utiliser ta macro tres souvent ;-)

if (cond)
TRAVAIL("%dn", MaFonctionQuiFaitUnCalcul() );

il y a une ambiguite sur le else et oblige a ecrire

if (cond) {
TRAVAIL("%dn", MaFonctionQuiFaitUnCalcul() );
}


Bien vu. Mais je crois que je ne l'aurais jamais vu, j'ai l'habitude de
mettre systematiquement les accolades apres un if (sauf quand je fais
des macros tres sales). Ca reste un tres bon argument.

Ca depend. Si on est au debut du projet, je prefere la deuxieme
solution, par contre s'il y a deja une grande quantite de code qui
"travaille", alors je prefere la premiere parce que je n'aurais pas
a propager les doubles parentheses partout ou cela est necessaire.


Par contre il faudra changer tous les Travail en TRAVAIL...


Ou renommer la fonction Travail en Travail_impl, et utiliser Travail
pour le nom de la macro. Tout depend de ce qu'il est possible/autorisé
de faire dans un cas reel.


Si je devais eventuellement adapter ta macro, j'irais plutot dans la
direction de

#define Travail !(DOIT_TRAVAILLER) ? (void)0 : Travail



C'est plaisant. Je ne savais pas qu'on pouvait avoir des valeurs void
dans les arguments de l'operateur ?: Quoi qu'il en soit, c'est elegant,
pour reprendre les contraintes de depart.

ou plutot que de seulement definir DOIT_TRAVAILLER, on lui donne les
valeurs 0 ou 1. De toute facon pas besoin d'un flag supplementaire.


Oui.

Cela peut marcher (je n'ai pas de contre exemple en tete) parce que
Travail ne renvoie rien, il devrait donc pas y avoir de cas ou la
precedence de ?: soit ambigue/plus faible.


Comme je n'ai plus vraiment en tete les règles de precedence des
operateurs, je prefere me taire et aller relire la doc...

MD


Avatar
Laurent Deniau
Par contre il faudra changer tous les Travail en TRAVAIL...


Ou renommer la fonction Travail en Travail_impl, et utiliser Travail
pour le nom de la macro.


Ce n'est pas necessaire, comme le montre mon exemple les deux peuvent
s'appeler Travail.

a+, ld.


Avatar
Dominique Vaufreydaz
Bonjour,

inline void Travail(char * format, ...)
Une fonction inline avec ellipsis ?



Euh, ellipsis ? Le '...' ? Ben oui, c'est comme ca que c'etait fait.

Doms.


Avatar
Dominique Vaufreydaz
Bonjour,

Ne pas négliger ses classiques :
#undef DOIT_TRAVAILLER
TRAVAIL(""); else std::cout << "Goto Hell!!!n";


Ouai, mais bon, la, faut vraiment qu'il le fasse expres
le gars !

Doms.

Avatar
Dominique Vaufreydaz
Bonjour,

Si je devais eventuellement adapter ta macro, j'irais plutot dans la
direction de

#define Travail !(DOIT_TRAVAILLER) ? (void)0 : Travail



D'autant plus elegant que ca m'enleve les warning "if : expression constante bla bla bla"
de Visual Studio 2005.

Merci. Doms.


1 2