The Google C++ Style is widely adopted by projects. It contains a brace omission guideline in Looping and branching statements:
For historical reasons, we allow one exception to the above rules: the curly braces for the controlled statement or the line breaks inside the curly braces may be omitted if as a result the entire statement appears on either a single line (in which case there is a space between the closing parenthesis and the controlled statement) or on two lines (in which case there is a line break after the closing parenthesis and there are no braces).
1 | // OK - fits on one line. |
In clang-format's predefined Google style for C++, there are two related style options:
1 | % clang-format --dump-config --style=Google | grep -E 'AllowShort(If|Loop)' |
The two options cause clang-format to aggressively join lines for the following code:
1 | for (int x : a) |
As a heavy debugger user, I find this behavior cumbersome.
1 | // clang-format --style=Google |
When GDB stops at the for
loop, how can I step into the
loop body? Unfortunately, it's not simple.
If I run step
, GDB will dive into the implementation
detail of the range-based for loop. It will stop at the
std::vector::begin
function. Stepping out and executing
step
again will stop at the std::vector::end
function. Stepping out and executing step
another time will
stop at the operator!=
function of the iterator type. Here
is an interaction example with GDB:
1 | (gdb) n |
You can see that this can significantly hinder the debugging process, as it forces the user to delve into uninteresting function calls of the range-based for loop.
In contrast, when the loop body is on the next line, we can just run
next
to skip the three uninteresting function calls:
1 | for (int x : a) // next |
The AllowShortIfStatementsOnASingleLine
style option is
similar. While convenient for simple scenarios, it can sometimes hinder
debuggability.
For the following code, it's not easy to skip the c()
and d()
function calls if you just want to step into
foo(v)
.
1 | if (c() && d()) foo(v); |
Many developers, mindful of potential goto fail
-like
issues, often opt to include braces in their code. clang-format's
default style can further reinforce this practice.
1 | // clang-format does not join lines. |
Other predefined styles
clang-format's Chromium style is a variant of the Google style and does not have the aforementioned problem. The LLVM style, and many styles derived from it, do not have the problem either.
1 | % clang-format --dump-config --style=Chromium | grep -E 'AllowShort(If|Loop)' |
A comparative look at other Languages
Go, Odin, and Rust require {}
for if statements but omit
()
, striking a balance between clarity and conciseness.
C/C++'s required ()` makes opt-in braces feel a bit verbose.
C3 and Jai, similar to C++, make {}
optional.