Root namespace: trillek
- Indentation: 4 spaces
- Avoid exceeding a line length of more than 80 characters.
- Lines longer than 120 characters are forbidden.
- Bracket Location:
if (x < 0) {
puts("Negative");
negative(x);
}
else {
puts("Non-negative");
nonnegative(x);
}
- Switch:
switch (suffix) {
case 'G':
case 'g':
{
// new scope
}
break;
case 'M':
default:
break;
}
- Namespaces :
namespace trillek {
namespace galaxy {
namespace jupiter {
static const int IM_IMPORTANT = 32;
class Foo {
public:
int x;
...
private:
int i;
...
};
...
} // End of namespace jupiter
} // End of namespace galaxy
} // End of namespace trillek
Give as descriptive a name as possible, within reason. Do not worry about saving horizontal space as it is far more important to make your code immediately understandable by a new reader. Do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word.
int price_count_reader; // No abbreviation.
int num_errors; // "num" is a widespread convention.
int num_dns_connections; // Most people know what "DNS" stands for.
int i,j,k,n,x,y,z; // Typical loop counter variables. Try to no abuse of it
int nerr; // Ambiguous abbreviation.
int n_comp_conns; // Ambiguous abbreviation.
int wgc_connections; // Only your group knows what this stands for.
int pc_reader; // Lots of things can be abbreviated "pc".
int cstmr_id; // Deletes internal letters.
NOTE: These points are still in discussion and subject to change
- Files: lowercase with underscores (_) or dashes (-)
- Classes/Structs/Enums: UpperCamelCase. Example :
class UrlTableTester { ...
struct UrlTableProperties { ...
// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;
typedef uint8_t Byte;
// enums
enum UrlTableErrors {
- Variables: lowercase and _ :
string table_name; // OK - uses underscore.
string tablename; // OK - all lowercase.
- Functions/Class methods: camelCase and _ to separate phrases. Example :
void purgueCacheLines();
class Foo {
public:
int getTotalFoos();
};
- Constants and Enum entries: all capitals and _ . Example:
const float PI = 3.1416....;
enum class Colors {
RED,
BLUE,
GREEN
};
constexpr float DESTRUCTION_RATIO = 0.1f;
We are going to use Doxygen, so we follow that style of comments. The most important is a short descriptive text of the class/struct/attribute. Entries for parameters or a detailed description are recommended, especially when doing something complex.
- Functions & methods :
/**
* \brief Returns a resource with the specified name.
*
* Bla bla bla bla bla bla bla ... (Optional detailed description)
* \param[in] const std::vector<Property> &properties The creation properties for the resource.
* \return bool True if initialization finished with no errors.
*/
or
/** \brief Remove and get a reference of an element
*
* Bla bla bla bla bla bla bla ... (Optional detailed description)
* \param key const K& the key of the element
* \param element T& a non-const reference that will contain the element
* \return bool true if removed, false otherwise
*/
or
/// \brief Remove and get a reference of an element
/**
* Bla bla bla bla bla bla bla ... (Optional detailed description)
* \param key const K& the key of the element
* \param element T& a non-const reference that will contain the element
* \return bool true if removed, false otherwise
*/
- For class attributes, constants, static vars, and global variables (ouch!) :
static const double PI = 3.14159265358979324; /// PI constant
static const double TAU = 2 * PI; /// 2*PI constant
static bool UberFlag; /// Uber important flag
/// (Optional detailed description) Indicates when we need to change the
/// polarity of the neutron beam in the dilithium chamber.
Whenever you need pointers, use std::unique_ptr
in most cases, std::shared_ptr
only when necessary and raw pointers only when it is required.
When you initialize a class or declare a pointer, set it to nullptr
. Also, when you free a pointer, first check if it is 1= of nullptr
and then free it, later set it to nullptr
. This allow to keep better control of memory managed by new/delete & malloc/free, as we can assume that if the pointer is nullptr
then was free or never was initialized.
Avoid the usage of global variables. Also try to avoid the usage of preprocessor constants, instead use static const
variables for constants as they have both type and scope, making them safer to use.
When you define a pointer or a reference, try to keep the * or & or && next to the type and not the name.
We use the .hpp
extension and use #ifndef
guards to protect headers. Also, we recommend putting a header comment block like this, just after the guards and before any #include
:
/**
* \brief Module that handles the neutrons in the dilithium chamber
* \file Neutrons.hpp
* \copyright License
*
*/
All source uses the .cpp
extension.
For included files that contains constants/data tables (Carmack's trick), we recommend using extension .inc
and add a comment explaining the contents of the included file.
Templatizing a member function is common, but specializing it for fixed parameter values and using the specialized functions requires some tricks. Here is an example using a templated function MyClass::MyFunction():
- Put the template declaration and optional default implementation in the class in the header file
MyClass.hpp
:
class MyClass {
template<class T> void Myfunction();
}
- Put the specialized functions in
MyClassTemplates.cpp
:
#include "MyClass.hpp"
template<> void MyClass::MyFunction<MyType1>() {...}
template<> void MyClass::MyFunction<MyType2>() {...}
- Put the
extern
declaration inMyClassTemplates.hpp
:
#include "MyClass.hpp"
extern template void MyClass::MyFunction<MyType1>();
extern template void MyClass::MyFunction<MyType2>();
- Include
MyClassTemplates.hpp
wherever the specialized functions are used, but do not include it inMyClassTemplates.cpp
as you would normally do.