2008-10-22 20 views
8

Dans un coding style question about infinite loops, certaines personnes ont mentionné qu'elles préféraient le style for (;;) car le style while (true) donnait des messages d'avertissement sur MSVC à propos d'une expression conditionnelle constante. Cela m'a beaucoup surpris, car l'utilisation de valeurs constantes dans les expressions conditionnelles est un moyen utile d'éviter #ifdef l'enfer. Par exemple, vous pouvez avoir dans votre tête:Valeur constante dans l'expression conditionnelle

#ifdef CONFIG_FOO 
extern int foo_enabled; 
#else 
#define foo_enabled 0 
#endif 

Et le code peut simplement utiliser un conditionnel et faire confiance au compilateur de elide le code mort quand CONFIG_FOO n'est pas défini:

if (foo_enabled) { 
    ... 
} 

Au lieu de avoir à tester CONFIG_FOO chaque fois foo_enabled est utilisé:

#ifdef CONFIG_FOO 
if (foo_enabled) { 
    ... 
} 
#endif 

Ce modèle de conception est utilisé tout le temps dans le noyau Linux (par exemple, include/linux/cpumask.h définit plusieurs AMRC os à 1 ou 0 lorsque SMP est désactivé et à un appel de fonction lorsque SMP est activé).

Quelle est la raison de cet avertissement MSVC? De plus, existe-t-il un meilleur moyen d'éviter l'enfer #ifdef sans avoir à désactiver cet avertissement? Ou est-ce un avertissement trop large qui ne devrait pas être activé en général?

Répondre

10

Un avertissement ne signifie pas automatiquement que le code est mauvais, juste suspicieux.

Personnellement, je commence à partir d'une position de permettre tous les avertissements que je peux, puis désactiver tout ce qui s'avère plus ennuyeux qu'utile. Celui qui se déclenche chaque fois que vous lancez quelque chose à un bool est généralement le premier à partir.

2

je crois qu'il est d'attraper des choses comme

if(x=0) 

lorsque vous vouliez dire

if(x==0) 
+0

Bon point. C'est une raison pour laquelle on voit des comparaisons "en arrière" comme "if (0 == x)" - si vous ratez one = sign, le compilateur l'attrape! – bog

+0

Si c'est ce qu'il veut attraper, ne pourrait-il pas attraper seulement cela (assignation dans un conditionnel) au lieu d'un avertissement plus général? – CesarB

+1

Cela génère un avertissement différent. Avec VC++, c'est: Compiler Warning (niveau 4) Affectation C4706 dans une expression conditionnelle – Ferruccio

0

Une façon simple d'éviter l'avertissement serait:

#ifdef CONFIG_FOO 
extern int foo_enabled; 
#else 
extern int foo_enabled = 0; 
#endif 
+0

Etes-vous sûr de pouvoir externaliser une variable et lui donner une valeur? Que faire si elle est initialisée à une valeur différente où elle est définie? "static const int foo_enabled = 0;" serait un meilleur choix. –

5

Je pense que la raison l'avertissement est que vous pourriez avoir par inadvertance une expression plus complexe qui évalue à une constante sans s'en rendre compte. Supposons que vous ayez une telle déclaration dans un en-tête:

const int x = 0; 

puis plus tard, loin de la déclaration de x, vous avez une condition comme:

if (x != 0) ... 

Vous pourriez ne pas remarquer que c'est une constante expression.