C++ - Force compile-Zeit-Fehler/Warnung auf impliziten fall-through switch
switch
Aussagen kann, super hilfreich, führen aber zu einem gemeinsamen Fehler behoben, wo ein Programmierer vergessen, eine break-Anweisung:
switch(val) {
case 0:
foo();
break;
case 1:
bar();
//oops
case 2:
baz();
break;
default:
roomba();
}
Werden Sie nicht bekommen eine Warnung offensichtlich, da fallen manchmal-durch ist ausdrücklich gewünscht. Guter coding style schlägt zu kommentieren, wenn Ihr fall-through ist gewollt, aber manchmal ist das nicht ausreichend.
Ich bin mir ziemlich sicher, dass die Antwort auf diese Frage ist Nein, aber: gibt es eine Möglichkeit, die derzeit (oder vorgeschlagen, in der Zukunft) in die Lage zu bitten, dass der compiler wirft einen Fehler (oder zumindest eine Warnung!) wenn Ihr case
nicht mindestens eine break;
oder etwas zum Effekt von //fallthru
? Es wäre schön, wenn eine defensive Programmierung die option für die Verwendung switch
Aussagen.
- Welche compiler verwenden Sie? Ich weiß, ich habe gesehen, discussion der Zugabe einer optionalen Warnung, die auf den gcc. Nicht sicher, was gekommen, allerdings noch nicht.
- klingt wie eine änderung, die potenziell die Pause legacy-code, wenn es ist alles andere als eine Warnung.
- Ich bin mit gcc 4.7
- Auch scheint es, dass einige statische code Analyzer wie CPPCheck fangen Sie dies, wenn Sie verwenden.
- Tatsächlich, cppcheck nicht zu finden, die den spezifischen fehlt break, führte zu dieser Frage 🙁
- Wenn Sie Polymorphismus statt der Umstellung werden Sie immer vermeiden, das Zeug! 😀
- Es war ein coverity-blog-post über dieses Thema vor ein paar Monaten.
- Ein weiterer Weg, um "zu vermeiden, all dieses Zeug", ist die Verwendung einer Funktion Tabelle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gut clang hat
-Wimplicit-fallthrough
die ich nicht kennen, aber sich über-Weverything
. Also dieser code gibt mir die folgende Warnung (sehen Sie es live):Die einzige Dokumentation, die ich finden kann für dieses flag ist in der Attribut-Referenz, die sagt:
- und bietet ein Beispiel, wie daneben expliziten fall-through:
Dieser Verwendung eine Attribut zu markieren expliziten fall-through-hat den Nachteil, nicht tragbar.
Visual Studio
einen Fehler generieren und diegcc
generiert die folgende Warnung:ist das ein problem, wenn Sie verwenden möchten
-Werror
.Habe ich versucht, diese mit
gcc 4.9
und es sieht aus wiegcc
bietet keine Unterstützung für diese Warnung:Als der GCC 7,
-Wimplicit-fallthrough
unterstützt wird und die__attribute__((fallthrough))
können verwendet werden, um die Warnungen zu unterdrücken, wenn fallthrough ist beabsichtigt. GCC erkennt "fallthrough" Kommentare in bestimmten Szenarien, es kann aber verwirrt werden,ziemlich leicht.Ich sehe nicht, einen Weg zu generieren, so wird eine Warnung für
Visual Studio
.Hinweis, Chandler Carruth erklärt, dass
-Weverything
ist nicht für die Produktion verwenden:aber es ist nützlich, um herauszufinden, welche Warnungen existieren.
C++17 verpasst
In C++17 wir erhalten das Attribut [[fallthrough]] bedeckt [dcl.attr.fallthrough]p1:
Sehen live-Beispiel mit dem Attribut.
-Weverything
(den die GCC-Leute sind offenbar ungern zu emulieren), ist so nützlich. Nein, die devs wahrscheinlich nicht verwenden es in der "offiziellen" Reihe von Warnungen, die zur Erstellung Ihrer Produktion code, aber es ist äußerst hilfreich, um ausführen die codebase gegen die es einmal in eine Weile zu sehen, ob es irgendwelche wirklich hilfreichen Warnungen, die Sie verpassen.-Wimplicit-fallthrough
ist nicht implementiert for C in Klang, ist aber im gccSchreibe ich immer eine
break;
vor jedercase
wie folgt:Diese Weise, es ist viel mehr offensichtlich für das Auge, wenn eine
break;
fehlt. Die erstenbreak;
überflüssig ist, nehme ich an, aber es hilft, konsequent zu sein.Dies ist eine konventionelle
switch
Erklärung, ich habe einfach verwendet, Leerzeichen in einer anderen Art und Weise, entfernen Sie den Zeilenumbruch, das ist normal nach einerbreak;
und vor der nächstencase
.#define CASE break; case
? 😉break;
s mehr visuell im Vordergrund.break
?break
vor dem erstencase
funktioniert. Und dies verursacht keine Probleme?break
vor einemcase
ist genau das gleiche wie mit einembreak
am Ende des vorherigen Satzes von Anweisungen. Ich mache die Einführung einerbreak
ganz am Anfang, vor dem erstencase
, aber das ändert nichts. In der Zusammenfassung, dies ist eine konventionelleswitch
Aussage, aber mit intelligenter Nutzung von whitespaceRat: wenn Sie konsequent setzen Sie eine Leerzeile zwischen case-Klauseln, die das fehlen eines 'break' ist mehr sichtbar in einer menschlichen skimming-code:
Dies ist nicht so effektiv, wenn es gibt eine Menge von code, der in einzelne Fall Klauseln, aber das ist eher eine schlechte code-Geruch an sich.
Hier eine Antwort zu zwanghaft hassen.
Zunächst
switch
Aussagen sind Lust auf gotos. Sie können kombiniert werden mit anderen control flow (bekannt, Duff ' s Device), aber die offensichtliche Analogie ist hier eine goto-oder zwei. Hier ist ein nutzloses Beispiel:Kann ich dieses empfehlen? Nein. In der Tat, wenn Sie erwägen, diese einfach zu beschriften, einen fall-through -, dann ist dein problem ist eigentlich etwas anderes.
Diese Art von code hat machen es sehr klar, dass ein fall-through-kann passieren in Fall 1, aber wie die anderen bits zeigen, dies ist eine sehr mächtige Technik im Allgemeinen, eignet sich auch zum Missbrauch. Seien Sie vorsichtig, wenn Sie es verwenden.
Vergessen
break
? Gut, dann wirst du auch gelegentlich vergessen, was Anmerkungen, die Sie wählen. Vergessen Konto für fall-through beim Wechsel einer switch-Anweisung? Du bist ein schlechter Programmierer. Beim ändern von switch-Anweisungen(oder wirklich alle code), müssen Sie zuerst verstehen Sie.Ehrlich gesagt, habe ich sehr selten diese Art von Fehler (vergessen, eine Pause) - mit Sicherheit weniger als ich gemacht anderen "gängigen" Fehler in der Programmierung (strict-aliasing, zum Beispiel). Um sicher zu sein, momentan mache ich (und empfehlen Sie zu tun hat), schreiben Sie einfach
//fallthrough
, da diese zumindest verdeutlicht die Absicht.Andere als das, es ist einfach eine Realität, dass Programmierer annehmen müssen. Korrektur Ihren code nach dem schreiben und finden das gelegentliche problem mit dem Debuggen. So ist das Leben.