-
Notifications
You must be signed in to change notification settings - Fork 475
Coding Standards Part 1 Style
Formatting guidelines are not overly strict. The important thing is that code is clear and readable with an appropriate amount of whitespace and reasonable length lines. A few best practices are also mentioned.
Tabs are not allowed, and a mixture of tabs and spaces is strictly forbidden. Modern autoindenting IDEs and editors require a consistent standard to be set. In EnergyPlus, we are using 4 spaces per indentation level. Set your IDE appropriately.
int myFunction(bool b)
{
if (b)
{
// do something
}
}[SM] There are good arguments for both tab and space indenting. Tabs have some benefits: 1) User controls indenting they want to see in their IDE, 2) With visual indent set to 3 or above commenting out lines doesn't break indentation alignment (this is very nice!), 3) Files are slightly smaller and thus should be very slightly faster to compile.
[JT] Consistency is the most important thing here. Tabs seem to have stuck at this point, so that is where we are
Code blocks must be enclosed by braces, i.e., {}. C/C++ allow one-line code blocks to be used without braces, but this can sometimes lead to hard-to-find bugs. So braces it is.
// Bad Idea
// this compiles and does what you want, but can lead to confusing errors if close attention is not paid.
for (int i = 0; i < 15; ++i)
std::cout << i << std::endl;
// Much better and readability is not impacted
// It's clear which statements are part of the loop (or if block, or whatever)
for (int i = 0; i < 15; ++i) {
std::cout << i << std::endl;
}Keep lines to a reasonable length.
// Bad Idea: hard to follow
if (x && y && myFunctionThatReturnsBool() && caseNumber3 && (15 > 12 || 2 < 3)) {
}
// Good Idea: logical grouping, easier to read
if (x && y && myFunctionThatReturnsBool()
&& caseNumber3
&& (15 > 12 || 2 < 3)) {
}[SM] Converted code is currently unwrapped pending decision on line wrapping. Since IDEs can soft-wrap for you one option is to leave lines unwrapped and let the user control visual wrapping to make best use of their display and preferences. Wrapping lines is hard to do nicely and some editors (looking at you, emacs!) do silly things with aligning wrapped lines on function parentheses that creates a maintenance burden.
Comment blocks should use //, not /* */. Using // makes it much easier to comment out a block of code while debugging.
// this function does something
int myFunc()
{
}To comment out this function block during debugging we might do:
/*
// this function does something
int myFunc()
{
}
*/which would be impossible if the function comment header used /* */.
For large code blocks, it's good to add a comment to the closing brace to identify the code block that it is closing. Here are some examples.
int myFunction()
{
for (int i = 0; i < max_i; ++i) {
for (int j = 0; j < max_j; ++j) {
for (int k = 0; k < max_k; ++k) {
if (array[i*max_k*max_j + j*max_k + k] > 0) {
// do a bunch of stuff
} // if (array[] > 0)
} // for (k)
} // for (j)
} // for (i)
} // myFunctionIsn't that better?
...with the member initializer list
// Bad Idea
class MyClass
{
public:
MyClass(int t_value)
{
m_value = t_value;
}
private:
int m_value;
};
// Good Idea
// C++'s memeber initializer list is unique to the language and leads to
// cleaner code and potential performance gains that other languages cannot
// match
class MyClass
{
public:
MyClass(int t_value)
: m_value(t_value)
{
}
private:
int m_value;
};Compiler definitions and macros are replaced by the pre-processor before the compiler is ever run. This can make debugging very difficult because the debugger doesn't know where the source came from.
// Good Idea
namespace my_project {
class Constants {
public:
static const double PI = 3.14159;
}
}
// Bad Idea
#define PI 3.14159;[AR] Certainly this is a good idea for constants, but are other uses of the preprocessor also frowned upon? What about DEBUG wrappers?
C++11 introduces nullptr which is a special type denoting a null pointer value. This should be used instead of 0 or NULL to indicate a null pointer.