Frage

Ein Kunde führte kürzlich eine statische Analyse der C -Codebasis meines Arbeitgebers durch und gab uns die Ergebnisse. Unter nützlichen Patches befand sich die Bitte, die Berühmten zu ändern do { ... } while(0) Makro zu do { ... } while(0,0). Ich verstehe, was ihr Patch tut (verwendete den Sequenzoperator, um Rückkehr Bewerten Sie den Wert des zweiten "0", also ist der Effekt der gleiche), aber es ist nicht klar, warum sie die zweite Form gegenüber der ersten Form bevorzugen.

Gibt es einen legitimen Grund, warum man die zweite Form des Makros bevorzugen sollte, oder ist die statische Analyse unseres Kunden übermäßig pedantisch?

War es hilfreich?

Lösung

Nun, ich werde eine Antwort machen:

Gibt es einen legitimen Grund, warum man die zweite Form des Makros bevorzugen sollte ...?

Nein, es gibt keinen legitimen Grund. Beide bewerten immer auf False, und jeder anständige Compiler wird den zweiten wahrscheinlich sowieso in die erste in der Baugruppe verwandeln. Wenn es einen Grund dafür gab, dass es in einigen Fällen ungültig wurde, ist C aus diesem Grund weit genug in der Nähe, um durch einen größeren Gurus entdeckt zu werden als ich.

Wenn Sie mögen, dass Ihr Code Owl-y-Augen auf Sie macht, verwenden Sie while(0,0). Andernfalls verwenden Sie das, was der Rest der C -Programmierwelt verwendet, und teilen Sie das statische Analyse -Tool Ihres Kunden mit.

Andere Tipps

Nur eine Vermutung, warum sie möglicherweise vorschlagen, die Verwendung zu verwenden

do { ... } while(0,0)

Über

do { ... } while(0)

Auch wenn es keinen Verhaltensunterschied gibt und keine Laufzeitkostenunterschiede zwischen den beiden sein sollte.

Ich vermute, dass sich das statische Analyse -Tool über das beschwert while Schleife wird im einfacheren Fall durch eine Konstante gesteuert und nicht wann 0,0 wird genutzt. Der Vorschlag des Kunden ist wahrscheinlich nur so, dass sie nicht ein paar falsch positive Aussagen aus dem Tool erhalten.

Zum Beispiel stoße ich gelegentlich auf Situationen, in denen ich eine bedingte Aussage haben möchte, die von einer Konstante gesteuert wird, aber der Compiler beschwert sich über eine Warnung vor einem bedingten Ausdruck, der eine Konstante bewertet. Dann muss ich durch ein paar Reifen springen, um den Compiler nicht mehr zu beschweren (da ich keine falschen Warnungen habe).

Der Vorschlag Ihres Kunden ist einer der Reifen, die ich gewohnt habe, diese Warnung zu beruhigen, obwohl er in meinem Fall a nicht kontrollierte while Schleife, es sollte mit einer Behauptung "immer fehlerhaft" umgehen. Gelegentlich habe ich einen Codebereich, der niemals ausgeführt werden sollte (vielleicht den Standardfall eines Schalters). In dieser Situation könnte ich eine Behauptung haben, die mit einer Nachricht immer fehlschlägt:

assert( !"We should have never gotten here, dammit...");

Aber mindestens ein Compiler benutze ich Probleme mit der Warnung vor dem Ausdruck, der immer auf False bewertet wird. Wenn ich es jedoch ändere in:

assert( ("We should have never gotten here, dammit...", 0));

Die Warnung verschwindet und alle sind glücklich. Ich vermute, dass auch das statische Analyse -Tool Ihres Kunden auch sein würde. Beachten Sie, dass ich im Allgemeinen das Stück Reifen verstecke, das hinter einem Makrosprung springt:

#define ASSERT_FAIL( x) assert( ((x), 0))

Es könnte schön sein, den Werkzeuganbieter mitzuteilen, dass er das Problem beheben soll, aber es könnte legitime Fälle geben, in denen sie tatsächlich eine Schleife diagnostizieren möchten, die durch einen konstanten booleschen Ausdruck gesteuert wird. Ganz zu schweigen von der Tatsache, dass selbst wenn Sie einen Werkzeuganbieter davon überzeugen, eine solche Änderung vorzunehmen, dies Ihnen nicht für das nächste Jahr oder so dauert, bis es tatsächlich dauert, um tatsächlich eine Lösung zu erhalten.

Verwendung while(0,0) verhindert, dass Microsoft Compiler eine Warnung vor einer Bedingung erzeugt, die eine Konstante ist (Warnung C4127).

Wenn diese Warnung aktiviert ist (z. B. mit /w4 oder /wall), kann sie mit diesem netten kleinen Trick durch Fall basierend geschlossen werden (Siehe diesen anderen Thread).

Bearbeiten: Seit Visual Studio 2017 15.3, while(0) emittiert keine Warnungen mehr (vgl. Konstante Bedingungen). Sie können Ihre loswerden (0,0) !

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top