My final (and looooong) polling post, I hope
Braces
The focus is curly braces. They are used a lot in C++ as we can see below:
for (const auto& item : list) {
}
while (something) {
}
do {
} while (something);
if (something) {
}
switch (value) {
case 1:
...
}
class MyClass {
};
enum MyEnum {
};
void my_function() {
}
auto my_lambda = [] () {
};
curly braces for empty control clauses
I think it is unnecessary to ask about it, but here we go: when a control clause has an empty body, can we use semicolon ;
or must we require to use empty braces { }
?
Examples:
// Case 1:
while (condition)
;
// Case 2:
while (condition);
// Case 3:
while (condition)
{ }
// Case 4:
while (condition) { }
Both first 2 cases are dangerous, but case 2 is particularly more dangerous because it “hides” (more) the end of the control:
while (condition);
{
// this is not a loop and it is always executed no matter the value of "condition" in "while" above
do_it();
}
Empty control clauses
- We may use semicolon
;
(we allow cases 1 and 2)
- We must use empty curly braces
{ }
(only cases 3 and 4 are acceptable)
to use or not to use
Must the use of curly braces be mandatory for statements with a single line control or are they optional in this case?
// If braces are optional, these are okay:
// If they are forbidden, only this style is allowed for single-line bodies:
if (condition)
do_it();
while (condition)
do_it();
for (;;)
do_it();
// If braces are optional, this is okay too:
// If mandatory, previous statement must be this way:
if (condition) {
do_it();
}
while (condition) {
do_it();
}
for (;;) {
do_it();
}
For single line control clauses
- Braces are optional
- Braces are mandatory
- Braces are forbidden
No matter what wins above, we refer only to single-line bodies: comments and multiple-lines commands must always use curly braces:
// Here is mandatory
if (condition) {
// Some comment
do_it();
}
if (condition) {
my_function(reallyLongParam1, reallyLongParam2, ...
reallyLongParam5);
}
This is supported by Qt, WebKit, Google and Haiku.
brace symmetry
For the if
statement, we may have the else
clause. If curly braces are not mandatory, we may have asymmetric use of {}
if if
clause has only a single line but else
clause has not (or vice-versa).
Example:
if (condition)
do_it();
else {
do_other_thing();
and_more();
}
Should we enforce brace symmetry in those cases? Qt (in “exception 2” subsection) and Google Style (in the last examples) emphasize it. WebKit does not: one “right” example makes an asymmetric usage like this:
if (condition)
doSomething();
else {
...
}
Brace lines
What line the starting (and ending) curly brace must be placed on?
WebKit
WebKit requires that the open brace must be placed on the line preceding the code block, except for function definitions:
// WebKit style
class MyClass {
...
};
namespace WebCore {
...
}
for (int i = 0; i < 10; ++i) {
...
}
if (condition) {
...
} else {
...
}
// functions behave differently:
int main()
{
...
}
Haiku
Haiku is not explicit, but its examples use a similar style WebKit uses: the difference is that, for classes, open brace is placed on the next line:
// Haiku style
namespace WebCore {
...
}
for (int i = 0; i < 10; ++i) {
...
}
if (condition) {
...
} else {
...
}
// functions and classes behave differently:
int main()
{
...
}
class MyClass
{
...
};
Google
Google wrote some points for function definitions:
- The open curly brace is always on the end of the last line of the function declaration, not the start of the next line.
- The close curly brace is either on the last line by itself or on the same line as the open curly brace.
For the rest, the document doesn’t say anything, but we can see they follow WebKit style in their examples.
Qt
Qt docs requires that the left brace on start of the next line only for class declarations and function definitions (lambda not included).
So it is styled as Haiku is.
Synfig
Synfig mixes it. As far as I can see, it originally used always open and close curly braces in a separate line:
Let’s vote!
I’ll split here for voting:
Loops
// option 1:
for (const auto& item : list) {
}
while (something) {
}
do {
} while (something);
// option 2:
for (const auto& item : list)
{
}
while (something)
{
}
do
{
} while (something);
Brace position for loops
for
, while
and do-while
have the open/left curly brace {
in the same line of the control statement (Qt, WebKit, Google, Haiku)
for
, while
and do-while
have the open/left curly brace {
in the next line (starting the line) (Synfig, sometimes)
Enum
// option 1:
enum MyEnum {
ITEM_1,
ITEM_2,
};
// option 2:
enum MyEnum
{
ITEM_1,
ITEM_2,
};
Brace position for enum
enum
must use the open/left curly brace {
in the same line of the control statement (Qt, WebKit, Google, Haiku)
enum
must use the open/left curly brace {
in the next line (starting the line)
Namespace
// option 1:
namespace {
...
}
// option 2:
namespace
{
...
}
Brace position for namespace
namespace
must use the open/left curly brace {
in the same line of the control statement (Qt, WebKit, Google, Haiku)
namespace
must use the open/left curly brace {
in the next line (starting the line)
Classes (and structs)
// option 1:
class MyClass {
};
// option 2:
class MyClass
{
};
Brace position for class definitions
class
must use the open/left curly brace {
in the same line of the control statement (WebKit, Google)
class
must use the open/left curly brace {
in the next line (starting the line) (Qt, Haiku)
regular functions
// option 1:
void my_function() {
}
// option 2:
void my_function()
{
}
Brace position for function definitions
- functions must use the open/left curly brace
{
in the same line of the control statement (Google)
- functions must use the open/left curly brace
{
in the next line (starting the line) (WebKit, Haiku, Qt)
lambda functions
//option 1:
auto my_lambda = [] () {
};
option 2:
auto my_lambda = [] ()
{
};
Brace position for lambda function definitions
- lambda functions must use the open/left curly brace
{
in the same line of the control statement (Qt, Google)
- lambda functions must use the open/left curly brace
{
in the next line (starting the line) (none explicitly)
(Haiku does not comment anything about lambda functions anywhere)
(WebKit does not say anything explicit, but the few (and single lined) lambda examples are inline)
if statement
Brace position for if statements
if
statement must use the open/left curly brace {
in the same line of the control statement (Qt, Google, WebKit, Haiku)
if
statement must use the open/left curly brace {
in the next line (starting the line)
// option 1:
if (condition) {
...
} else { // same line
...
}
// option 2:
if (condition) {
...
}
else { // next line
...
}
Brace position for else statements
else
statement must be in the same line of close brace: } else
else
statement must be in the next line
switch statements
None of mentioned code style say anything explicitly about switch
.
We can discuss 2 parts:
- the mandatory braces for
switch
itself and
- the ‘optional’ braces for
case
s (mandatory if there are variable declaration in a case
).
// option 1:
switch (value) {
case 1:
...
}
// option 2:
switch (value)
{
case 1:
...
}
Brace position for switch statements
switch
statement must use the open/left curly brace {
in the same line of the control statement (Qt, Google, WebKit, Haiku)
switch
statement must use the open/left curly brace {
in the next line (starting the line)
// option 1:
switch (value) {
case 1: { // on same line
...
}
}
// option 2:
switch (value) {
case 1: // { on next line
{
...
}
}
Brace position for case statements
case
statement must use the open/left curly brace {
in the same line of the control statement (Qt, Google, WebKit, Haiku)
case
statement must use the open/left curly brace {
in the next line (starting the line)
Can control body be in the same line as control statement?
Is this acceptable? No matter whether using braces or not.
For if
, for
, while
… Sometimes code is written like below in Synfig:
while (reading) { i++; } // Can we accept those single line statements?
if (!ready) return;
for (;;) { do_something(); ++i; }
Can control body be in the same line as control statement? Somehow related to empty body voted uuuup there.
- No, we must not allow it
- Yes, but only if it is just a single instruction
- Yes, we allow it
one variable declaration per line
static inline
As discussed in a previous post, the return type of a method implementation is written in the previous line of method name.
However, I forgot that sometimes there are some method specifiers like static
and inline
. Should they be listed in the line before the return type (example below) or in the same line as the return type?
static
and inline
specifiers for class method implementations:
- In the same line of the return type (most cases in Synfig)
- In the previous line of the return type (example above)
Constructor initializer list :
On what line should we place the :
for constructor initializer list?
Haiku
// The ':' always comes on its own line, initializers following
Foo::Foo(int32 param)
:
Bar(int32* param),
fMember(param),
fPointerMember(NULL)
{
...
}
// When everything fits on one line:
MyClass::MyClass(int var) : some_var_(var) {
DoSomething();
}
// If the signature and initializer list are not all on one line,
// you must wrap before the colon and indent 4 spaces:
MyClass::MyClass(int var)
: some_var_(var), some_other_var_(var + 1) {
DoSomething();
}
// When the list spans multiple lines, put each member on its own line
// and align them:
MyClass::MyClass(int var)
: some_var_(var), // 4 space indent
some_other_var_(var + 1) { // lined up
DoSomething();
}
// As with any other code block, the close curly can be on the same
// line as the open curly, if it fits.
MyClass::MyClass(int var)
: some_var_(var) {}
MyClass::MyClass(Document* document)
: MySuperClass()
, m_myMember(0)
, m_document(document)
{
}
MyOtherClass::MyOtherClass()
: MySuperClass()
{
}
File_handle::File_handle(const string& name, const string& mode)
: f{fopen(name.c_str(), mode.c_str())}
{
if (!f)
throw runtime_error{"File_handle: could not open " + name + " as " + mode};
}
Where should be the colon :
for constructor initializer list?
- On its own line (Haiku - see its example above)
- At ‘start’ of initilizations line (the rest)
- At the end of the constructor signature line (before the initialization line)
AND THAT’S IT. WOW