2008-10-22 18 views
8

In einer coding style question about infinite loops haben einige Leute erwähnt, dass sie den for (;;) -Stil bevorzugen, da der while (true) -Stil Warnmeldungen auf MSVC über einen konstanten Ausdruck gibt, der konstant ist.Konstanter Wert in Bedingungsausdruck

Das hat mich sehr überrascht, da die Verwendung von konstanten Werten in bedingten Ausdrücken ein nützlicher Weg ist, #ifdef Hölle zu vermeiden. Zum Beispiel können Sie in der Kopfzeile haben:

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

und der Code kann einfach eine bedingte verwenden und den Compiler vertrauen den toten Code elide wenn CONFIG_FOO nicht definiert ist:

if (foo_enabled) { 
    ... 
} 

statt für CONFIG_FOO zu testen, die jedes Mal foo_enabled verwendet:

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

Dieses Entwurfsmuster die ganze Zeit im Linux-Kernel verwendet wird (zB include/linux/cpumask.h mehrere macr definiert os auf 1 oder 0, wenn SMP deaktiviert ist, und auf einen Funktionsaufruf, wenn SMP aktiviert ist.

Was ist der Grund für diese MSVC-Warnung? Gibt es außerdem einen besseren Weg, die #ifdef-Hölle zu vermeiden, ohne diese Warnung zu deaktivieren? Oder ist es eine zu breite Warnung, die generell nicht möglich sein sollte?

Antwort

10

Eine Warnung bedeutet nicht automatisch, dass der Code schlecht ist, nur verdächtig aussehende.

Persönlich beginne ich von einer Position zu aktivieren alle Warnungen, die ich kann, dann schalten Sie alle, die mehr als lästig erweisen als nützlich. Derjenige, der immer dann feuert, wenn man etwas in einen Bool wirft, ist normalerweise der Erste, der geht.

2

Ich glaube, es ist Dinge zu fangen wie

if(x=0) 

wenn Sie

if(x==0) 
+0

Guter Punkt. Dies ist ein Grund, warum man "rückwärts" Vergleiche wie "if (0 == x)" sieht - wenn man ein = -Zeichen vermisst, fängt der Compiler es! – bog

+0

Wenn es das ist, was es fangen will, könnte es nicht nur das (Zuweisung innerhalb einer Bedingung) statt einer allgemeineren Warnung fangen? – CesarB

+1

Das erzeugt eine andere Warnung. Mit VC++ ist es: Compiler-Warnung (Level 4) C4706 Zuweisung innerhalb der Bedingung Ausdruck – Ferruccio

0

Ein einfacher Weg, um die Warnung zu vermeiden, gemeint wäre:

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

Sind Sie sicher, dass Sie eine Variable extern und gleichzeitig einen Wert geben können? Was ist, wenn es auf einen anderen Wert initialisiert wird, wo es definiert ist? "statisch const int foo_enabled = 0;" wäre eine bessere Wahl. –

5

denke ich, den Grund für Die Warnung besteht darin, dass Sie versehentlich einen komplexeren Ausdruck haben, der eine Konstante ergibt, ohne dies zu bemerken. Angenommen, Sie haben eine Erklärung, wie diese in einem Header:

const int x = 0; 

dann später, weit weg von der Deklaration von x, haben Sie eine Bedingung wie:

if (x != 0) ... 

Sie nicht feststellen können, dass es eine Konstante ist Ausdruck.

Verwandte Themen