Einrückungsstil

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche
Dieser Artikel oder nachfolgende Abschnitt ist nicht hinreichend mit Belegen (beispielsweise Einzelnachweisen) ausgestattet. Die fraglichen Angaben werden daher möglicherweise demnächst entfernt. Bitte hilf der Wikipedia, indem du die Angaben recherchierst und gute Belege einfügst. Näheres ist eventuell auf der Diskussionsseite oder in der Versionsgeschichte angegeben. Bitte entferne zuletzt diese Warnmarkierung.

Als Einrückungsstil (engl. indent style) wird die Art und Weise bezeichnet, Quelltext von Programmen zur besseren Lesbarkeit einzurücken und umschließende Syntax-Elemente wie geschweifte Klammern {} zu positionieren. Als alternativer Name ist daher auch manchmal „Klammerstil“ (engl. brace style) anzutreffen.

Für die Programmiersprache C gibt es vier verbreitete Einrückungsstile, die auch in Programmier- und Skriptsprachen mit C-ähnlicher Syntax wie C++, Java, JavaScript, Perl oder C# übernommen wurden.

Die Positionierung der geschweiften Klammern ist wahrscheinlich das umstrittenste Element eines Programmierstils.

Elemente des Einrückungsstils[Bearbeiten]

Der Einrückungsstil bezieht sich auf:

  • Positionierung umschließender Syntax-Elemente, insbesondere {} und ()
  • Tiefe der Einrückung
  • Verwendung von Leerzeichen vor { und (
  • Verwendung von Tabulatorzeichen zur Einrückung.

Häufig wird empfohlen, einen Quelltext nicht so zu formatieren, dass die Einrückung erst mit einer Veränderung der Tabulatorschrittweite auf einen anderen Wert sichtbar wird, z. B. 4 statt 8 Zeichen. Die allermeisten Editoren rücken als Voreinstellung den Tabulator um 8 Leerzeichen ein. Um Probleme in der Darstellung in Bezug auf die Tabulatorschrittweite gänzlich zu vermeiden, raten die meisten Einrückungsstile von der Verwendung von Tabulatorzeichen grundsätzlich ab.

Positionierung umschließender Syntax-Elemente[Bearbeiten]

Siehe auch: Blockstruktur

Umschließende Syntax-Elemente sind solche Syntax-Elemente einer Sprache, die zur Gruppierung einer unbestimmten Zahl von Elementen dienen, nicht ausschließlich aber insbesondere dann, wenn sich die Elemente über mehrere Quelltextzeilen erstrecken. In Sprachen mit C-ähnlicher Syntax, z. B. C++, Java und C#, in Sprachen mit Pascal-ähnlicher Syntax, z. B. Modula-2, Oberon und Cluster sowie einigen weiteren Sprachen fällt diesen Elementen bei der Gestaltung eines Quelltextes in Bezug auf seine Syntax und seine Lesbarkeit eine zentrale Bedeutung zu.

Positionierung in Pascal[Bearbeiten]

Pascal-ähnliche Sprachen verwenden zur Umschließung eigens dafür definierte Schlüsselwörter, meist BEGIN, DO und END. In der Praxis wird eine Positionierung dieser Elemente nur selten diskutiert, meist wird sie so vorgenommen, wie von Niklaus Wirth in der Literatur vorgeführt. Dabei steht BEGIN noch in der Einrückung des äußeren Blocks auf einer eigenen Zeile, DO dagegen wird am Ende der vorherigen Zeile zusammen mit dem das DO benötigende Statement geschrieben. Der Inhalt des durch BEGIN oder DO eingeleiteten Blocks wird bis ausschließlich zum END eingerückt. Das END steht ausgerückt, d. h. in der Einrückung des äußeren Blocks schließlich wieder auf einer eigenen Zeile.

Beispiel: Positionierung der umschließenden Syntax-Elemente in Oberon

 PROCEDURE Add(VAR x, y: INTEGER)
 BEGIN
   WHILE (y != 0) DO
     y := y - 1;
     x := x + 1;
   END
 END Add;

Positionierung in C[Bearbeiten]

C-ähnliche Sprachen verwenden zur Umschließung ein Paar von geschweiften Klammern { und }. In der Praxis können diese Klammern nahezu beliebig positioniert werden, so dass sich mehrere verschiedene Stile entwickelt haben, von denen keiner als dominant zu bezeichnen ist.

Dieser Abschnitt bedarf einer Überarbeitung. Näheres ist auf der Diskussionsseite angegeben. Hilf mit, ihn zu verbessern, und entferne anschließend diese Markierung.

Positionierung in XML- und SGML-basierten Sprachen[Bearbeiten]

In XML- und SGML-basierten Sprachen, z. B. HTML, hat sich durchgesetzt, die Inhalte von Elementen zwischen Start-Tag und End-Tag einzurücken. Für Attribute findet man immer häufiger eine mehrzeilige Aufteilung, besonders, wenn Übersichtlichkeit gefragt ist.

Beispiel: Einrückung in einem XHTML-Quelltext

 <?xml version="1.0"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
     <head>
         <title>Einrückung in XML</title>
     </head>
     <body>
         <h1>Einrückung in XML</h1>
         <p>
             Dieses Dokument ist ein Beispiel für Einrückung in XML / SGML.
             <br />
             In diesem Beispiel beträgt die Einrückungstiefe 4 Leerzeichen.
         </p>
     </body>
 </html>

Beispiel: Einrückung in einem Ant-Quelltext

 <?xml version="1.0"?>
 <!--
   - Daimonin Editor build file
   -->
 <project
     name    = "Daimonin Editor"
     default = "compile"
 >
     <target
         name        = "compile"
         description = "compile Daimonin Editor"
     >
         <javac
             srcdir   = "src"
             destdir  = "classes"
             encoding = "utf-8"
             source   = "1.5"
             target   = "1.5"
             debug    = "no"
         />
     </target>
 </project>

Einrückungstiefe[Bearbeiten]

Die Einrückungstiefe bestimmt, wie weit der Inhalt eines Blocks eingerückt wird. Besonders weit verbreitet sind Einrückungstiefen um 4 oder 8 Leerzeichen, aber auch 2 oder 3 Leerzeichen ist nicht selten anzutreffen. Letztendlich stellt die Einrückungstiefe einen Kompromiss zwischen einer durch große Einrückungstiefe möglichst deutlichen Sichtbarkeit der Einrückung einerseits und einer möglichst großen erhaltenen Zeilenlänge andererseits dar. Die erhaltene Zeilenlänge lässt sich wie folgt berechnen: erhaltene Zeilenlänge = Zeilenlänge - Schachtelungstiefe * Einrückungstiefe. Bei einer Zeilenlänge von 80 Zeichen, einer Einrückungstiefe von 4 Leerzeichen und einer Schachtelungstiefe von 3 Ebenen beträgt die erhaltene Zeilenlänge also noch 68 Zeichen.

Beispiel: Java-Quelltext mit Einrückungstiefe 2 Leerzeichen

 public class Hello {
   public static void main(String... args) {
     if (args.length > 0) {
       for (String arg : args) {
         System.out.println("Hello, " + arg + "!");
       }
     } else {
       System.out.println("Hello, world!");
     }
   }
 }

Beispiel: Java-Quelltext mit Einrückungstiefe 4 Leerzeichen

 public class Hello {
     public static void main(String... args) {
         if (args.length > 0) {
             for (String arg : args) {
                 System.out.println("Hello, " + arg + "!");
             }
         } else {
             System.out.println("Hello, world!");
         }
     }
 }

Beispiel: Java-Quelltext mit Einrückungstiefe 8 Leerzeichen

 public class Hello {
         public static void main(String... args) {
                 if (args.length > 0) {
                         for (String arg : args) {
                                 System.out.println("Hello, " + arg + "!");
                         }
                 } else {
                         System.out.println("Hello, world!");
                 }
         }
 }

Wie man sieht, nimmt mit wachsender Einrückungstiefe die deutliche Sichtbarkeit der Einrückung zu, die Zeilen werden jedoch länger, was bei einer begrenzten Textbreite weniger Platz für Ausdrücke innerhalb einer Zeile lässt.

Verwendung von Tabulator oder Leerzeichen[Bearbeiten]

Die Einrückung eines Quelltextes lässt sich in den meisten Programmiersprachen wahlweise mit Leerzeichen oder mit Tabulator vornehmen. Die meisten Compiler sehen darin keinen Unterschied, die Wahl bleibt also dem Programmierer überlassen.

Es gibt jedoch Argumente, die für oder gegen eine Einrückung mit Leerzeichen bzw. Tabulator sprechen. Für eine Einrückung mit Leerzeichen spricht, dass die Einrückungstiefe grundsätzlich gleich bleibt und die Einrückung so stets erkennbar ist, unabhängig davon, welche Tabulatorschrittweite verwendet wird. Für eine Einrückung mit Tabulator spricht, dass sich jeder Entwickler selbst die Tabulatorschrittweite einstellen und somit seine persönliche Einrückungstiefe bestimmen kann.

Wichtiger als die Wahl des Einrückungsstils ist es, den gewählten Stil konsequent einzuhalten, da eine Mischung zu Problemen bei der Darstellung führen kann.

Beispiel: Quelltext mit gemischter Einrückung (sowohl Tabulator als auch Leerzeichen), der mit einer Tabulatorschrittweite von 4 erstellt und 8 angezeigt wurde

public class Hello {
    public static void main(String... args) {
        if (args.length > 0) {
            for (String arg : args) {
                System.out.println("Hello, " + arg + "!");
            }
        } else {
            System.out.println("Hello, world!");
        }
    }
}

Die Darstellung könnte durch eine Umstellung der Tabulatorschrittweite korrigiert werden. Für einige wenige Editoren, z. B. vim, lassen sich in den Quelltexten Steuerinformationen unterbringen, die den Editor automatisch auf die verwendete Tabulatorschrittweite stellen. Diese Editoren stellen jedoch die Ausnahme dar, außerdem mangelt es an einem einheitlichen Standard für solche Einstellungen. Ohne diese Möglichkeiten muss der Programmierer bei gemischten Quelltexten jeden Quelltext optisch betrachten, die Tabulatorschrittweite erraten und entsprechend neu einstellen.

Bekannte Einrückungsstile[Bearbeiten]

Dieser Artikel oder nachfolgende Abschnitt ist nicht hinreichend mit Belegen (beispielsweise Einzelnachweisen) ausgestattet. Die fraglichen Angaben werden daher möglicherweise demnächst entfernt. Bitte hilf der Wikipedia, indem du die Angaben recherchierst und gute Belege einfügst. Näheres ist eventuell auf der Diskussionsseite oder in der Versionsgeschichte angegeben. Bitte entferne zuletzt diese Warnmarkierung.

Hinweis zu den Beispielen[Bearbeiten]

Die Code-Beispiele dienen dazu, den Einrückungsstil zu demonstrieren. Ihr Inhalt ist kaum sinnvoll.

1TBS / K&R / Kernel / Linux / UNIX / „West Coast“ / Stroustrup / Java / Sun[Bearbeiten]

Beispiel: GNU-Beispiel in 1TBS

         if (x < foo(y, z)) {
                 qux = bar[4] + 5;
         } else {
                 while (z) {
                         qux += foo(z, z);
                         z--;
                 }
                 return ++x + bar();
         }

Der Name 1TBS kommt aus dem Hacker-Jargon und steht für „One True Brace Style“, was übersetzt soviel bedeutet wie „einzig wahrer Klammern-Stil“. Der Name bezieht sich darauf, dass dieser Stil von den C-Erfindern Brian W. Kernighan und Dennis Ritchie definiert wurde.

Die Positionierung der öffnenden Klammern am Zeilenende ist gleichermaßen beliebt wie verhasst. Mit schlechten Entwicklungswerkzeugen besteht bei Unachtsamkeit die Gefahr, öffnende Klammern zu übersehen und schließende zu vergessen.

Andererseits bietet dieser Stil zwei Vorteile:

  • Die Darstellung von wesentlich mehr Code in der gleichen Zahl Zeilen.
  • Unselbstständige Folgeblöcke werden an der schließenden geschweiften Klammer unter einer schließenden geschweiften Klammer in derselben Spalte erkannt.

Die überwiegende Mehrheit der Java- und ECMAScript-Programmierer verwendet diesen Stil. Auch Perl-Programmierer verwenden meist 1TBS, weil sie es sowieso bevorzugen, ihre Programme möglichst kurz zu halten.

C-Code verwendete früher 8 Leerzeichen pro Einrückungsschritt, heute sind auch manchmal 4 oder 3 Leerzeichen anzutreffen. Bei Java und C++ ist eine Einrückung um 4 Leerzeichen die Regel.

Variation: Original K&R / Kernel / Linux / UNIX / Stroustrup[Bearbeiten]

Beispiel: GNU-Beispiel in K&R

 int f(int x, int y, int z)
 {
         if (x < foo(y, z)) {
                 qux = bar[4] + 5;
         } else {
                 while (z) {
                         qux += foo(z, z);
                         z--;
                 }
                 return ++x + bar();
         }
 }

Dieser Programmierstil wurde von den C-Erfindern Brian W. Kernighan und Dennis Ritchie (K&R) in ihrem Buch The C Programming Language (Deutscher Titel: Programmieren in C) sowie zusammen mit Ken Thompson bei der Entwicklung von UNIX und seines Kernels verwendet. Auch die Code Conventions von Linus Torvalds für Linux schlagen diesen Stil vor.

Die dargestellte Einrückungstiefe ist die beim Linux-Kernel verwendete. Die Einrückung untergeordneter Syntaxelemente beträgt dort 8 Leerzeichen. Dies erleichtere die Lesbarkeit auch nach 20-stündiger Bildschirmarbeit. Von einer Einrückung von mehr als 3 Ebenen wird abgeraten und stattdessen eine Umstrukturierung des Quelltextes vorgeschlagen.[1]

Im Gegensatz zum durchgängigen Einsatz des 1TBS, wie z. B. beim Java-Stil, wird bei der Definition von Funktionen auf den Allman-Stil zurückgegriffen.

Die Ausnahmeregelung für die Funktionen in C findet mehrere Begründungen:

  • Funktionen können nicht geschachtelt werden.
  • K&R verwenden ebenfalls exakt diese Positionierung der Klammern
  • Die Ausnahmeregelung bietet eine besonders hohe Lesbarkeit bei umbrochenen Funktionsdefinitionen:
 static int
 kwrite_args(struct posix_log_entry *rec_hdr, va_list args,
         unsigned char **pvardata)
 {
         // ...
 }

Wird dieser Stil auf C++ angewandt, nennt man ihn auch Stroustrup nach dem Erfinder von C++, welcher den K&R-Stil um Elemente für C++ erweitert hat. Für alle neuen Elemente, z. B. Klassen, werden geschweifte Klammern ans Ende gestellt:

<!-- Original aus http://www.research.att.com/~bs/bs_faq2.html#layout-style -->
 class C : public B {
 public:
         // ...
 };

Variation: Java / Sun[Bearbeiten]

Beispiel: GNU-Beispiel in Java-Stil

 int f(int x, int y, int z) {
     if (x < foo(y, z)) {
         qux = bar[4] + 5;
     } else {
         while (z) {
             qux += foo(z, z);
             z--;
         }
         return ++x + bar();
     }
 }

Dieser Stil wird von Sun für die Programmiersprache Java empfohlen.[2] Auch bei C++ ist dieser Stil häufig anzutreffen. Auf die Ausnahmeregelung, die geschweiften Klammern von Methoden (=objektorientierte Funktion) gemäß Allman zu positionieren, wird verzichtet, da Methoden als Elemente von Klassen geschachtelt sind.

Aufgrund der häufiger auftretenden Schachtelung wird eine Einrückung um 4 statt 8 Leerzeichen bevorzugt.

Allman / BSD / „East Coast“[Bearbeiten]

Beispiel: GNU-Beispiel in Allman-Stil

 int f(int x, int y, int z)
 {
     if (x < foo(y, z))
     {
         qux = bar[4] + 5;
     }
     else
     {
         while (z)
         {
             qux += foo(z, z);
             z--;
         }
         return ++x + bar();
     }
 }

Dieser Stil wurde nach Eric Allman benannt, der eine Vielzahl an BSD-Werkzeugen geschrieben hat, weshalb dieser Stil auch nicht ganz korrekt BSD-Stil heißt.

Als nachteilig wird von manchen Programmierern angesehen, dass dieser Stil einen hohen Zeilenverbrauch hat. Pro Block wird eine zusätzliche Zeile im Vergleich mit 1TBS benötigt. In C, C++ und Sprachen mit vergleichbaren Präprozessoren gibt es jedoch Situationen, in denen dieser Stil auch wesentliche Vorteile gegenüber 1TBS zeigt, und zwar beim Einsatz von bedingter Compilierung für alternative Blockeinleitungen.

Beispiel: Vorteil des Allman-Stils bei bedingter Compilierung von Blockeinleitungen

<!-- Zitat aus main.cpp des Daimonin 3D Clients, kann geaendert werden. -->
 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
 #else
 int main(int argc, char **argv)
 #endif
 {
     // ...
 }

Die Zahl der Klammern insgesamt bleibt auch beim Einsatz bedingter Compilierung gleich, was wichtig für die korrekte Zuordnung von öffnenden und schließenden Klammern in Texteditoren mit entsprechender Funktionalität ist.

Hinweis: Dieser Stil wird zwar häufig BSD-Stil genannt, für den BSD-Kernel wird jedoch wie für UNIX und Linux 1TBS verwendet, wie in den Style-Manpages der verschiedenen BSD-Derivate nachzulesen ist.[3][4]

Horstmann[Bearbeiten]

Der Horstmann-Stil ist eine Abwandlung des Allman-Stils, bei dem das erste Statement nach der öffnenden geschweiften Klammer direkt in derselben Zeile geschrieben wird. Der Code von oben sieht dann so aus:

 int f(int x, int y, int z)
 {   if (x < foo(y, z))
     {   qux = bar[4] + 5;
     }
     else
     {   while (z)
         {   qux += foo(z, z);
             z--;
         }
         return ++x + bar();
     }
 }

Für VCS-Tools ist dieser Stil problematisch. Fügt man ein neues Statement zwischen dem "{" und dem ersten Statement ein, erscheint diese Änderung als "eine Zeile wird durch 2 Zeilen ersetzt" statt "eine neue Zeile wurde eingefügt". Das heißt, die ursprüngliche Zeile wird als "geändert" markiert, obwohl sie semantisch gleich geblieben ist.

Whitesmith-Stil[Bearbeiten]

Der Whitesmith-Stil wurde ursprünglich in der Dokumentation des ersten kommerziellen C-Compiler eingesetzt. Dieser Stil war in frühen Windows-Programmierhandbüchern populär, unter anderem im Programmer's Guide to Windows (Durant, Carlson & Yao), in Programming Windows (Petzold) sowie Windows 3.0 Power Programming Techniques (Norton & Yao).

 int f(int x, int y, int z)
     {
     if (x < foo(y, z))
         {
         qux = bar[4] + 5;
         }
     else
         {
         while (z)
             {
             qux += foo(z, z);
             z--;
             }
         return ++x + bar();
         }
     }

Der Vorteil dieses Stils ist, dass der Block sich klar von der Kontrollanweisung absetzt und im Gegensatz zu Allman-Stil nicht den Lesefluss des Blocks unterbricht.

GNU-Stil[Bearbeiten]

Beispiel: Original GNU-Beispiel

 int f (int x, int y, int z)
 {
     if (x < foo (y, z))
       qux = bar[4] + 5;
     else
       {
         while (z)
           {
             qux += foo (z, z);
             z--;
           }
         return ++x + bar ();
       }
 }

Dieser Programmierstil ist vor allem in GNU-Projekten der Free Software Foundation zu finden und wird von ihr empfohlen. Außerhalb der Free Software Foundation ist er eher selten anzutreffen und auch innerhalb der Free Software Foundation wird er nicht von allen verwendet.

Das genannte Beispiel wurde den GNU Coding Standards entnommen.[5] Die anderen Beispiele sind in Bezug auf Einrückung und Klammernsetzung umformatiert.

Verfechter des GNU-Stils beschreiben ihn deshalb als besonders lesbar, weil den geschweiften Klammern in der Positionierung/Einrückung eine eigene Ebene zukommt. Gegner hingegen argumentieren, dass dadurch ein gewisses Chaos bei der Quelltextformatierung entstehe; die Lesbarkeit und konsequente Einrückung würden erschwert.

Siehe auch[Bearbeiten]

Einzelnachweise[Bearbeiten]

  1. http://www.kernel.org/doc/Documentation/CodingStyle
  2. http://www.oracle.com/technetwork/java/codeconvtoc-136057.html
  3. http://www.openbsd.org/cgi-bin/man.cgi?query=style
  4. http://www.freebsd.org/cgi/man.cgi?query=style
  5. http://www.gnu.org/prep/standards/standards.html#Formatting

Weblinks[Bearbeiten]