Was ist der Unterschied zwischen K & R und One True Brace Style (1TBS)?

48

Ich habe den Wikipedia-Artikel über Einrückungsstile gelesen , verstehe ihn aber immer noch nicht. Was ist der Unterschied zwischen K & R und 1TBS?

GavinR
quelle
Ich habe irgendwo gelesen, dass der Stil in K & R von räumlichen Überlegungen bestimmt wurde - dh um den vertikalen Raum zu verringern, den der Code im Buch einnahm.
ChrisF
@ChrisF reduziert auch den vertikalen Platz auf dem Bildschirm. Wenn wir 80 col x 25 Line Terminals hatten, war es das wert!
Martin Beckett
7
Apples "goto fail" ist ein großartiges Beispiel für einen schwerwiegenden Fehler, der mit 1TBS sicher verhindert worden wäre: imperialviolet.org/2014/02/22/applebug.html
4
Der Fehler von Apple konnte auch verhindert werden, indem die Anweisung in eine einzelne Zeile gestellt, Korrektur gelesen, ein Dead Code Checker verwendet oder eine einrückungsempfindliche Sprache verwendet wurde.
Cees Timmerman
1
@ CeesTimmerman, .. oder mit Tests ...
Thoni56

Antworten:

76

Der größte Unterschied zwischen K & R und der One True Brace Style (1TBS) ist , dass in dem 1TBS, alle if, else, while, und forAussagen haben das Öffnen und Schließen Klammer, auch wenn sie nicht notwendig ist. Der Zweck besteht darin, das Einfügen neuer Anweisungen zu vereinfachen und genau zu wissen, wie sie gruppiert werden.

Als Beispiel:

K & R:

int i;
for (i = 0; i < 10; i++)
  printf("Hi.");

1 TB:

int i;
for (i = 0; i < 10; i++) {
  printf("Hi");
}
Thomas Owens
quelle
20

K & R sieht so aus:

if (x) 
    a();
else {
    b();
    c();
}

Das heißt: Klammern werden nur bei Bedarf verwendet, Klammern werden in derselben Zeile wie die Steueranweisung geöffnet, Klammern werden in einer eigenen Zeile geschlossen.

Der "one true brace style" (1TBS oder OTBS) verwandelt eine einzelne kontrollierte Anweisung in eine zusammengesetzte Anweisung, indem er sie in geschweifte Klammern einschließt:

if (x) {
    a();
} else {
    b();
    c();
}

Der Allman-Stil geht etwas weiter als 1 TB und erzwingt vertikale Abstände, indem die öffnende Klammer ebenfalls auf einer Linie platziert wird:

if (x) 
{
    a();
}
else 
{
    b();
    c();
}

Bearbeiten:

Ich versuche immer noch genau herauszufinden, wie es sich als "arrogant" qualifiziert, zu sagen: "Dennis Ritchie war ein äußerst kluger Kerl, der nicht nur eine gute Sprache erfunden hat, sondern auch einen wirklich guten Klammerstil dafür entwickelt hat."

Für diejenigen, die darauf bestehen, dass es ohnehin arrogant ist, gibt es eine kleine Herausforderung: Gehen Sie zu Sourceforge, Github (usw.) und wählen Sie Projekte mit dem K & R-Klammerstil aus. Sehen Sie sich die Aufzeichnungen der Fehler und Commits an und versuchen Sie, einen einzelnen Fehler zu finden , der durch den verwendeten Klammerstil verursacht wurde.

Wenn Sie nicht so viel arbeiten möchten, versuchen Sie es mit einer einfachen statistischen Analyse. Vergleichen Sie Projekte mit verschiedenen Klammerstilen und prüfen Sie, ob Sie "Bimodalität" anzeigen können - einen statistisch signifikanten Unterschied in der Anzahl der Fehler (Schweregrad usw.), der mit dem Klammerstil korreliert.

Ich habe beides vor ein paar Jahren gemacht und konnte weder einen einzigen Fehler finden, den ich Klammerstilen zuordnen konnte, noch konnte ich irgendetwas finden, das sich einer statistisch signifikanten Korrelation zwischen den beiden annäherte. Im Durchschnitt hatten diejenigen, die K & R-Klammern verwendeten, etwas weniger Fehler, aber der Unterschied war viel zu gering, um als statistisch signifikant eingestuft zu werden.

Da es erwähnt wurde, werde ich die Situation mit Makros mit mehreren Anweisungen kommentieren. Ein Makro, das mehrere Anweisungen enthält, diese aber nicht in geschweifte Klammern einschließt, weist einen Fehler auf. Meine Aufgabe ist es nicht , Code zu schreiben, der diesen Fehler überdeckt. Im Gegenteil, meine Aufgabe ist es, diesen Fehler so schnell wie möglich zu finden und auszurotten.

Das Schreiben von Code in der Hoffnung, Fehler zu vertuschen, damit sie nicht diagnostiziert und nicht behoben werden, ist geradezu böse. Nennen Sie das arrogant, wenn Sie möchten, aber ich halte das nicht für beinahe verhandelbar. Fehler sollten gefunden und behoben werden, nicht vertuscht. Je länger es sie gibt, desto wahrscheinlicher ist es, dass ihre Behebung viel schwieriger und teurer wird.

Jerry Sarg
quelle
1
Löschte alle Kommentare, da sie zu Streitereien und Lärm abgefallen waren. Wenn du einen gültigen Punkt hast, poste ihn als Antwort. Wenn du eine Diskussion haben willst, nimm sie mit zum Chat
ChrisF
8
Setzen die 1tbs das} und sonst nicht in eine Zeile? Es geht darum, vertikalen Raum zu sparen und gleichzeitig die wundervolle Symmetrie zu bewahren!
Martin Beckett
4
@ Jerry - gut jeder gute heilige Krieg braucht ein paar Schismen ;-)
Martin Beckett
6
Ich werde scheitern. Ich werde scheitern.
Jamie Pate
9
Ja, um @ JamiePates Kommentar zu verfolgen, der den Apple SSL-Fehler darstellt, der hier analysiert wird . Es gibt eine ifAnweisung mit eingerückten Anweisungen dahinter, sodass der Eindruck entsteht, dass beide Anweisungen bedingt ausgeführt werden. Es gibt aber keine Zahnspange! Die zweite Anweisung ist wirklich jenseits der ifund wird immer ausgeführt, also der Bug.
Colin D Bennett
9

Das Problem im Allgemeinen mit dem KR-Klammerstil ist das Code-Refactoring. Wenn Sie Code verschieben, können Sie leicht übersehen, dass es keine geschweiften Klammern um etwas gibt, verschieben Sie es falsch (oder verschieben Sie etwas darunter, wenn Sie denken, dass es unter bestimmten Bedingungen ausgeführt wird) und kratzen Sie sich dann entweder am Kopf, wenn etwas nicht mehr funktioniert, oder seien Sie unglücklich und dabei Ein Codebereich ist nicht gut getestet und der Fehler bleibt unbemerkt, bis ein schwarzer Hut einen Weg findet, ihn auszunutzen. Ein schneller Einstieg in den Debugger findet das Problem leicht, wenn Sie es bemerken, aber wenn Sie es nicht tun ...

Justin Swanhart
quelle
2
dies scheint nur wiederholen Punkt gemacht und erklärt in früheren Antworten
gnat
1
Ich glaube nicht, dass die anderen Antworten genau erklären, wie das Problem im alltäglichen Code auftritt. Sie erklären, was OTB ist, aber nicht, warum es tatsächlich wichtig ist. Kommentare könnten das ansprechen, aber nicht die Antworten.
Justin Swanhart