This article describes popular brace styles (aka indent styles). Hopefully it provides enough information to help people decide on which indent style to use.
{}
. Though the brace style and the indent style describe different things, they are so bound to each other that usually the term brace style is also used to describe an indent style and vice versa. So the terms brace style and indent style are used as synonyms for the hyperonym of brace style plus indent style. Because of that but to not loose precision, that combination will be called brace and indent style throughout this article, whereas brace style will refer to the positioning of braces and the indent style to the indention.
This chapter discusses different kinds of brace and indent styles. It starts with a list and summary about each brace and indent style, including a list of code conventions for each of these styles. Then it compares the brace and indent styles to each other. It concludes with a recommendation which indent style to use.
Most of the popular programming languages use curly braces for subordinate syntax elements.
The C programming language (C) was the first popular curly brace language. C was originally invented by Brian W. Kernighan and Dennis Ritchie in 1972. The book The C Programming Language
by Kernighan and Ritchie is the most popular (non-normative) reference about C. Its first edition describes K&R C, the original version. The second edition describes C89 which is the C programming language as standardized by the ANSI. Hackers refer to the first edition as old testament
, to the second edition as new testament
and to Brian W. Kernighan and Dennis Ritchie as the first prohpets
.
The K&R brace style resembles the brace positioning and indention as used by the first prophets in their books.
#include <stdio.h> typedef struct { int x; int y; } point2d_t; int main(int argc, char *argv[]) { if (argc > 2) { printf("More than 1 argument.\n"); } else { printf("Less than 2 arguments.\n"); } switch (argc) { case 1: case 2: case 3: printf("0-2 argumnets.\n"); break; default: printf("More than 2 arguments.\n"); } return 0; }
The K&R style rules are:
The brace style, aka indent style, determines how for readability a program's source code is indented and surrounding syntax elements like curly braces {}
are positioned. For the C programming language there are 4 wide spread indent styles which are also applied to languages with syntax similar to C like C++, Java, ECMAScript, Perl or C#.
To be really precise, there's a small difference between the brace style and the indent style. The brace style determines where braces like {
and }
are placed. The indent style determines how subordinate program elements are indented. But these topics are so closely related to each other, that usually the terms brace style and indent style are used synonymously.
To be precise, there is a slight difference between brace style and indent style. The brace style determines the positioning of surrounding syntax elements like {}
. The indent style determines the indention level for indented syntax elements. But these two aspects are so closely related to each other that it doesn't make sense to separate them from each other.
The brace and indent style relates to:
{}
and ()
{
and (
It is recommended to format a source code in a way that is independent of the tabulator setting. The indention should have the same quality of visibility no matter whether the tabulator is set to show as 4 or as 8 space. Most editors use 8 space for a tabulator per default. To avoid problems with tabulator width, never mix tabs and whitespace for indention. Cher's opinion is that unless you're writing a Makefile, you should never use tabulator for indention but use normal space only.
Surrounding syntax elements in a programming language are those syntax elements that group an undefined number of elements, not only but most often when these elements span more than a single line of source code. In languages with C-like syntax, e.g. C++, Java and C#, in languages with Pascal-like syntax, e.g. Modula-2, Oberon and Cluster as well as some other languages, the positioning of these elements is of high importance for the readability and thus maintainability of a source code.
Pascal-like languages use certain keywords for surrounding, like BEGIN
, DO
and END
. Usually their positioning isn't frequently discussed but simply done the same way as Niklaus Wirth, father of these languages, demonstrated in his literature.
PROCEDURE Add(VAR x, y: INTEGER) BEGIN WHILE (y != 0) DO y := y - 1; x := x + 1; END END Add; |
C-like languages use a pair of curly braces {
and }
for surrounding. There's more than one popular brace style, with 1TBS being the predominant amongst professionals and Allman being the one preferred by beginners. The styles for C are explained in a chapter of their own.
In XML- and SGML-based languages, e.g. HTML, it's usual to indent the content lines between a start-tag and the end-tag of an element.
<?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="en"> <head> <title>Indention in XML</title> </head> <body> <h1>Indention in XML</h1> <p> This docment is an example for indention in XML / SGML. <br /> In this example the indention depth is 4 spaces. </p> </body> </html> |
<?xml version="1.0"?> <!-- ~ Daimonin Editor build file --> <project name = "Daimonin Editor" default = "compile" > <target name = "compile" description = "Compiles Daimonin Editor" > <javac srcdir = "src" destdir = "classes" encoding = "utf-8" source = "1.5" target = "1.5" debug = "no" /> </target> </project> |
The indention depth determines how far the contents of a block are indented. The indention depth is specified by the indent style. The indention level is the level of subordinate syntax. The indention level is derived from the program logic. Though the indention level cannot be directly influenced by a code convention, it often makes sense to specify a soft maximum limit for the indention level. This forces programmers to think about their program's structure and encapsulate functionality more often.
Wide spread are indention depths of 4 or 8 spaces, but you'll also see 2 or 3 spaces sometimes. Finally, indention depth is a compromise between a high indention depth for good visibility of the indention on one hand and as much retained line length on the other hand. The retained line length is easy to calculate: retained line length = line length - indention level * indention depth. For a line length of 80 chars, an indention depth of 4 and an indention level of 3 the retained line length is 68 chars.
public class Hello public static void main(final String... args) { if (args.length > 0) { for (final String arg : args) { System.out.println("Hello, " + arg + "!"); } } else { System.out.println("Hello, world!"); } } } |
public class Hello public static void main(final String... args) { if (args.length > 0) { for (final String arg : args) { System.out.println("Hello, " + arg + "!"); } } else { System.out.println("Hello, world!"); } } } |
public class Hello public static void main(final String... args) { if (args.length > 0) { for (final String arg : args) { System.out.println("Hello, " + arg + "!"); } } else { System.out.println("Hello, world!"); } } } |
As you can clearly see, with increasing indention depth the visibility of the indention increases. On the other hand with increasing indention depth the lines become longer, what with limited text width will leave less rooms for expressions within a line.
Most programming languages don't care about whitespace themselves. Whether you use space or tabs for indention is of no matter to most compilers. So the choice is with the programmer.
Yet there are pros and cons for indention with either space or tab.
Spaces only | Tabs only | Mixed | |
---|---|---|---|
Pro |
|
| |
Con |
|
|
Pro space is that the indention depth stays visible independently of the tab width setting. Pro tab is that every developer could configure her own tab width and thus displayed indention depth. Con tab is the different behaviour of different software in terms of the tab character. While some programs display a tab char as predefined number of spaces (default: 8), others use the tab char to fill to the next column divisable by the tab width without reminder, which leads to different display.
start = 0; end = 20; |
start = 0; end = 20; |
Advocates of spaces as well as advocates of tabs usually deny mixing both kinds of indention. Mixing both kinds of indention will inevitably lead to problems with the display of indention as soon as different tab widths were used.
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!"); } } } |
The display could be corrected by changing the tab width configuration. For some editors, e.g. ↗vim, it is possible to add control information to the source code which will setup the editor automatically with the desired tab width. But such editors are rare, and there is no standard for such kinds of settings. Without this possibility, mixed source code needs to be viewed by the developer first to guess the correct tab width setting and set it up.
The code examples serve to demonstrate the code style only. Their content has pretty much no meaning. This especially is valid for the writing of "z--". It was used because nearly all examples are taken from the GNU Coding Standards and were reformatted according to the indention style that they demonstrate. In fact, "--z" on older CPUs with older compilers will quite likely be a bit faster in execution (1 machine instruction less, 1 register less) than "z--".
if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo(z, z); z--; } return ++x + bar(); } |
The name 1TBS originates from the ↗Jargon File and means "One True Brace Style". The name relates to the fact that this style was defined by the C-inventors Brian W. Kernighan and Dennis Ritchie.
The positioning of the opening brace at the end of the line probably is loved and hated in equal measure. With bad development tools carelessness brings the danger of not seeing opening braces and thus forgetting closing braces.
On the other hand, this style has four significant advantages, a combination of which can only be found in this style:
The vast majority of Java and ECMAScript programmers uses this style. Also Perl programmers most often use 1TBS because they prefer to keep their programs short anyway.
C-Code usually used an indention depth of 8 spaces in earlier times, today 4 or 3 spaces are also frequently found. For Java and C++ an indention depth of 4 is common.
More information about the advantages of 1TBS can be found in the last chapter of this article, Recommendation.
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo(z, z); z--; } return ++x + bar(); } } |
This indent style was used by the C inventors Brian W. Kernighan and Dennis Ritchie (K&R) in their book The C Programming Language as well as together with Ken Thompson during the development of UNIX and its kernel. The code conventions from Linus Torvalds for Linux suggest this style as well as those of BSD.
The displayed indention depth is the one used with the Linux-kernel. The indention of subordinate syntax elements is 8 spaces. According to the Linux code convention this should keep the readability of the indention at a high level even after 20 hours of screen work. The Linux code conventions discourages an indention level of more than 3 levels. If source code needs more than 3 levels, it should be restructured.
In contrast to the universal use of 1TBS as it could be found at the Java style, the definition of functions in original K&R uses an exception. This exception leads back to the original K&R convention for specifying function parameters. It could be regarded obsolete today but still is popular for historical reasons as a reminiscence of Kernighan and Ritchie.
If this style is applied to C++, it's also called Stroustrup, named after the inventor of C++, which simply extended K&R for the new elements. For new elements like classes the opening brace is always put at the end of the line
class C : public B { public: // ... }; |
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo(z, z); z--; } return ++x + bar(); } } |
This style is the style that SUN recommends for Java. For C++ this style can also often be found, and it is identical with the styles recommended by Larry Wall for Perl or what the ECMA uses for ECMAScript (aka JavaScript). Last but not least it is what Steve McConnel recommends in his book Code Complete. The exception rule for functions is dropped here. Usually this style is used with an indention depth of 4 spaces.
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo(z, z); z--; } return ++x + bar(); } } |
This style is named after Eric Allman, who wrote a lot of utilities for the BSD family of operating systems, which also is a reason why this style is sometimes incorrectly referred to as the BSD style. Please note that this style might sometimes be called BSD style, but that this is wrong. For BSD itself, just as for UNIX and Linux, 1TBS is used. You can read about this in the man pages of the different BSD derivates e.g. for ↗FreeBSD and ↗OpenBSD.
This style is usually preferred by newbes to C-derived programming languages for being the easiest. Despite the fact that the inventors of C, UNIX and BSD use 1TBS, this style is very common for C.
The main disadvantage of this style is the waste of precious screen lines. Per block at least one additional line is needed compared to 1TBS. In C, C++ and similar languages with comparable preprocessors there is one single situation where this style shows an advantage over 1TBS.
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif { // ... } |
The number of opening braces stays the same even in the case of conditional compilation, which might be useful for the correct association of opening and closing brace pairs in text editors which offer such a feature (e.g. vim).
The Horstmann style is a variation of the Allman style that puts the first statement of a block in the same line as the opening brace.
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo(z, z); z--; } return ++x + bar(); } } |
Goal of the relatively young Horstmann style is to combine some advantages of the Allman style (easy association of opening and closing brace in the same column) with the K&R style (saving screen lines).
int f (int x, int y, int z) { if (x < foo (y, z)) haha = bar[4] + 5; else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } } |
This programming style is mainly found in GNU projects of the Free Software Foundation, it's their recommended style. Outside the FSF this style is only rarely used, and even within the FSF it's not the vast majority that use it.
The above example is a 1:1 quote from the GNU Coding Standards. (All other examples are just reformats of this)
Advocates of the GNU style describe it as extraordinarily readable, because the braces get their own level in positioning / indention. Opponents on the other hand argue that this leads to some amount of chaos in source formatting; the readability and consistent indention were hardened and this kind of formatting would be error prone.
int f (int x, int y, int z) { if (x < foo (y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } } |
This style was made popular by Whitesmiths C, one of the first C compilers with wide spread availability. Today, this style is only rarely used and found nearly only amongst a few hackers. Whitesmiths usually was used with tabs and a tab width of 8 spaces.
This style is mainly used in the Pico programming language. The lack of a return statement and the usage of braces as terminators instead of separators made the following style popular in Pico:
stuff(n): { x: 3 * n; y: doStuff(x); y + x } |
This style is nearly never found outside the Pico programming language.
The banner style indents the closing syntax element together with the subordinates. There are two variants.
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } } |
int f(int x, int y, int z) { if (x < foo(y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } } |
<?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" id="style" > <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> |
There also are languages in which there are no syntax tokens to group subordinate syntax elements. Instead, indention only is used. Python is an example for such a language. The subordination level is only done using indention and indention level.
def f(x, y, z): if x < foo(y, z): haha = bar[4] + 5 else: while z: haha += foo(z, z) z -= 1 x += 1 return x + bar() |
The rationale behind this in Python is that in a readable source code, subordinates are indented properly anyway, therefore braces for subordinates are redundant. Additionally, using the indention only removes the source of errors where code has different meaning than suggested by the indention, which sometimes might be the case in C and other {}-languages.
Note: This recommendation differs from my original ↗German Wikipedia article. The truth is here, not in Wikipedia.
Because of its many advantages, 1TBS definitely is the choice to go, unless you use Python which offers an even more reasonable choice. The following table rates the different styles according to the specified criteria.