| Code style and coding guidelines |
| ================================ |
| |
| Based on |
| |
| * "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996 – 2011. |
| The original document is available at `<http://geosoft.no/development/cppstyle.html>`_ |
| |
| * NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines". |
| The original document available at `<http://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_ |
| |
| 1. Code layout and file naming |
| ------------------------------ |
| |
| 1.1. The code layout should generally follow the GNU coding standard layout for C, |
| extended it to C++. |
| |
| * Do not use tabs for indentation. |
| * Indentation spacing is 2 spaces. |
| * Lines should be within a reasonable range. Lines longer than 100 columns should |
| generally be avoided. |
| |
| 1.2. Whitespace |
| |
| * Conventional operators (``if``, ``for``, ``while``, and others) should be |
| surrounded by a space character. |
| * Commas should be followed by a white space. |
| * Semicolons in for statments should be followed by a space character. |
| |
| Examples: |
| |
| .. code-block:: c++ |
| |
| a = (b + c) * d; // NOT: a=(b+c)*d |
| |
| while (true) { // NOT: while(true) |
| ... |
| |
| doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d); |
| |
| for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){ |
| ... |
| |
| 1.3. Namespaces should have the following form: |
| |
| .. code-block:: c++ |
| |
| namespace example { |
| |
| code; |
| moreCode; |
| |
| } // namespace example |
| |
| Note that code inside namespace is **not** indented. Avoid following: |
| |
| .. code-block:: c++ |
| |
| // NOT |
| // |
| // namespace example { |
| // |
| // code; |
| // moreCode; |
| // |
| // } // namespace example |
| |
| 1.4. The class declarations should have the following form: |
| |
| .. code-block:: c++ |
| |
| class SomeClass : public BaseClass |
| { |
| public: |
| ... <public methods> ... |
| protected: |
| ... <protected methods> ... |
| private: |
| ... <private methods> ... |
| |
| public: |
| ... <public data> ... |
| protected: |
| ... <protected data> ... |
| private: |
| ... <private data> ... |
| }; |
| |
| ``public``, ``protected``, ``private`` may be repeated several times without |
| interleaving (e.g., public, public, public, private, private) if this allows better |
| readability of the code. |
| |
| Nested classes can be defined in appropriate visibility section, either in methods |
| block, data block, or in a separate section (depending which one provides better code |
| readability). |
| |
| 1.5. Method and function definitions should have the following form: |
| |
| .. code-block:: c++ |
| |
| void |
| someMethod() |
| { |
| ... |
| } |
| |
| void |
| SomeClass::someMethod() |
| { |
| ... |
| } |
| |
| 1.6. The ``if-else`` class of statements should have the following form: |
| |
| .. code-block:: c++ |
| |
| if (condition) { |
| statements; |
| } |
| |
| if (condition) { |
| statements; |
| } |
| else { |
| statements; |
| } |
| |
| if (condition) { |
| statements; |
| } |
| else if (condition) { |
| statements; |
| } |
| else { |
| statements; |
| } |
| |
| or (less preferred): |
| |
| .. code-block:: c++ |
| |
| if (condition) |
| { |
| statements; |
| } |
| else if (condition) |
| { |
| statements; |
| } |
| else |
| { |
| statements; |
| } |
| |
| 1.7. A ``for`` statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| for (initialization; condition; update) { |
| statements; |
| } |
| |
| or (less preferred): |
| |
| .. code-block:: c++ |
| |
| for (initialization; condition; update) |
| { |
| statements; |
| } |
| |
| An empty for statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| for (initialization; condition; update) |
| ; |
| |
| This emphasizes the fact that the for statement is empty and it makes it obvious for |
| the reader that this is intentional. Empty loops should be avoided however. |
| |
| 1.8. A ``while`` statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| while (condition) { |
| statements; |
| } |
| |
| or (less preferred): |
| |
| .. code-block:: c++ |
| |
| while (condition) |
| { |
| statements; |
| } |
| |
| 1.9. A ``do-while`` statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| do { |
| statements; |
| } while (condition); |
| |
| 1.10. A ``switch`` statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| switch (condition) { |
| case ABC: |
| statements; |
| // Fallthrough |
| |
| case DEF: |
| statements; |
| break; |
| |
| case XYZ: |
| statements; |
| break; |
| |
| default: |
| statements; |
| break; |
| } |
| |
| or (less preferred): |
| |
| .. code-block:: c++ |
| |
| switch (condition) |
| { |
| case ABC: |
| statements; |
| // Fallthrough |
| |
| case DEF: |
| statements; |
| break; |
| |
| case XYZ: |
| statements; |
| break; |
| |
| default: |
| statements; |
| break; |
| } |
| |
| The explicit ``Fallthrough`` comment should be included whenever there is a case |
| statement without a break statement. Leaving the break out is a common error, and it |
| must be made clear that it is intentional when it is not there. |
| |
| 1.11. A ``try-catch`` statement should have the following form: |
| |
| .. code-block:: c++ |
| |
| try { |
| statements; |
| } |
| catch (Exception& exception) { |
| statements; |
| } |
| |
| or (less preferred): |
| |
| .. code-block:: c++ |
| |
| try |
| { |
| statements; |
| } |
| catch (Exception& exception) |
| { |
| statements; |
| } |
| |
| 1.12. The incompleteness of split lines must be made obvious. |
| |
| .. code-block:: c++ |
| |
| totalSum = a + b + c + |
| d + e; |
| function(param1, param2, |
| param3); |
| for (int tableNo = 0; tableNo < nTables; |
| tableNo += tableStep) { |
| ... |
| } |
| |
| Split lines occurs when a statement exceed the 80 column limit given above. It is |
| difficult to give rigid rules for how lines should be split, but the examples above should |
| give a general hint.In general: |
| |
| * Break after a comma. |
| * Break after an operator. |
| * Align the new line with the beginning of the expression on the previous line. |
| |
| Exceptions: |
| |
| * The following is the standard practice with operator<<: |
| |
| .. code-block:: c++ |
| |
| std::cout << "Something here " |
| << "Something there" << std::endl; |
| |
| 1.13. When class variables need to be initialized in the constructor, the initialization |
| should take the following form: |
| |
| .. code-block:: c++ |
| |
| SomeClass::SomeClass(int value, const std::string& string) |
| : m_value(value) |
| , m_string(string) |
| ... |
| { |
| } |
| |
| Each initialization should be put on a separate line, starting either with the colon |
| for the first initialization or with comma for all subsequent initializations. |
| |
| 2. Naming Conventions |
| --------------------- |
| |
| 2.1. C++ header files should have the extension ``.hpp``. Source files should have the |
| extension ``.cpp`` |
| |
| File names should be all lower case. If the class name |
| is a composite of several words, each word in a file name should be separated with a |
| dash (-). A class should be declared in a header file and defined in a source file |
| where the name of the files match the name of the class. |
| |
| :: |
| |
| my-class.hpp, my-class.cpp |
| |
| |
| 2.2. Names representing types must be written in English in mixed case starting with upper case. |
| |
| .. code-block:: c++ |
| |
| class MyClass; |
| class Line; |
| class SavingsAccount; |
| |
| 2.3. Variable names must be written in English in mixed case starting with lower case. |
| |
| .. code-block:: c++ |
| |
| MyClass myClass; |
| Line line; |
| SavingsAccount savingsAccount; |
| int theAnswerToLifeTheUniverseAndEverything; |
| |
| 2.4. Named constants (including enumeration values) must be all uppercase using underscore |
| to separate words. |
| |
| .. code-block:: c++ |
| |
| const int MAX_ITERATIONS = 25; |
| const std::string COLOR_RED = "red"; |
| static const double PI = 3.14; |
| |
| In some cases, it is a better (or is the only way for complex constants in header-only |
| classes) to implement the value as a method: |
| |
| .. code-block:: c++ |
| |
| int |
| getMaxIterations() |
| { |
| return 25; |
| } |
| |
| 2.5. Names representing methods or functions must be commands starting with a verb and |
| written in mixed case starting with lower case. |
| |
| .. code-block:: c++ |
| |
| std::string |
| getName() |
| { |
| ... |
| } |
| |
| double |
| computeTotalWidth() |
| { |
| ... |
| } |
| |
| 2.6. Names representing namespaces should be all lowercase. |
| |
| .. code-block:: c++ |
| |
| namespace model { |
| namespace analyzer { |
| |
| ... |
| |
| } // namespace analyzer |
| } // namespace model |
| |
| 2.7. Names representing generic template types should be a single uppercase letter |
| |
| .. code-block:: c++ |
| |
| template<class T> ... |
| template<class C, class D> ... |
| |
| However, when template parameter represents a certain concept and expected to have a |
| certain interface, the name should be explicitly spelled out: |
| |
| .. code-block:: c++ |
| |
| template<class FaceBase> ... |
| template<class Packet> ... |
| |
| 2.8. Abbreviations and acronyms must not be uppercase when used as name. |
| |
| .. code-block:: c++ |
| |
| exportHtmlSource(); // NOT: exportHTMLSource(); |
| openDvdPlayer(); // NOT: openDVDPlayer(); |
| |
| 2.9. Global variables should have ``g_`` prefix |
| |
| .. code-block:: c++ |
| |
| g_mainWindow.open(); |
| g_applicationContext.getName(); |
| |
| In general, the use of global variables should be avoided. Consider using singleton |
| objects instead. |
| |
| 2.10. Private class variables should have ``m_`` prefix. Static class variables should have |
| ``s_`` prefix. |
| |
| .. code-block:: c++ |
| |
| class SomeClass |
| { |
| private: |
| int m_length; |
| |
| static std::string s_name; |
| }; |
| |
| |
| 2.11. Variables with a large scope should have long (explicit) names, variables with a small |
| scope can have short names. |
| |
| Scratch variables used for temporary storage or indices are best kept short. A |
| programmer reading such variables should be able to assume that its value is not used |
| outside of a few lines of code. Common scratch variables for integers are ``i``, |
| ``j``, ``k``, ``m``, ``n`` and for characters ``c`` and ``d``. |
| |
| 2.12. The name of the object is implicit, and should be avoided in a method name. |
| |
| .. code-block:: c++ |
| |
| line.getLength(); // NOT: line.getLineLength(); |
| |
| The latter seems natural in the class declaration, but proves superfluous in use, as |
| shown in the example. |
| |
| 2.13. The terms ``get/set`` must be used where an attribute is accessed directly. |
| |
| .. code-block:: c++ |
| |
| employee.getName(); |
| employee.setName(name); |
| |
| matrix.getElement(2, 4); |
| matrix.setElement(2, 4, value); |
| |
| 2.14. The term ``compute`` can be used in methods where something is computed. |
| |
| .. code-block:: c++ |
| |
| valueSet.computeAverage(); |
| matrix.computeInverse() |
| |
| Give the reader the immediate clue that this is a potentially time-consuming operation, |
| and if used repeatedly, he might consider caching the result. Consistent use of the term |
| enhances readability. |
| |
| 2.15. The term ``find`` can be used in methods where something is looked up. |
| |
| .. code-block:: c++ |
| |
| vertex.findNearestVertex(); |
| matrix.findMinElement(); |
| |
| Give the reader the immediate clue that this is a simple look up method with a minimum |
| of computations involved. Consistent use of the term enhances readability. |
| |
| 2.16. Plural form should be used on names representing a collection of objects. |
| |
| .. code-block:: c++ |
| |
| vector<Point> points; |
| int values[]; |
| |
| Enhances readability since the name gives the user an immediate clue of the type of |
| the variable and the operations that can be performed on its elements. |
| |
| 2.17. The prefix ``n`` should be used for variables representing a number of objects. |
| |
| .. code-block:: c++ |
| |
| nPoints, nLines |
| |
| The notation is taken from mathematics where it is an established convention for |
| indicating a number of objects. |
| |
| |
| 2.18. The suffix ``No`` should be used for variables representing an entity number. |
| |
| .. code-block:: c++ |
| |
| tableNo, employeeNo |
| |
| The notation is taken from mathematics where it is an established convention for |
| indicating an entity number. An elegant alternative is to prefix such variables with |
| an ``i``: ``iTable``, ``iEmployee``. This effectively makes them named iterators. |
| |
| 2.19. The prefix ``is``, ``has``, ``need``, or similar should be used for boolean variables and |
| methods. |
| |
| .. code-block:: c++ |
| |
| isSet, isVisible, isFinished, isFound, isOpen |
| needToConvert, needToFinish |
| |
| 2.20. Complement names must be used for complement operations, reducing complexity by |
| symmetry. |
| |
| :: |
| |
| get/set, add/remove, create/destroy, start/stop, insert/delete, |
| increment/decrement, old/new, begin/end, first/last, up/down, min/max, |
| next/previous (and commonly used next/prev), open/close, show/hide, |
| suspend/resume, etc. |
| |
| Pair ``insert/erase`` should be preferred. ``insert/delete`` can also be used if it |
| does not conflict with C++ delete keyword. |
| |
| 2.21. Variable names should not include reference to variable type (do not use Hungarian |
| notation). |
| |
| .. code-block:: c++ |
| |
| Line* line; // NOT: Line* pLine; |
| // NOT: Line* linePtr; |
| |
| size_t nPoints; // NOT lnPoints |
| |
| char* name; // NOT szName |
| |
| 2.22. Negated boolean variable names should be avoided. |
| |
| .. code-block:: c++ |
| |
| bool isError; // NOT: isNoError |
| bool isFound; // NOT: isNotFound |
| |
| 2.23. Enumeration constants recommended to prefix with a common type name. |
| |
| .. code-block:: c++ |
| |
| enum Color { |
| COLOR_RED, |
| COLOR_GREEN, |
| COLOR_BLUE |
| }; |
| |
| 2.24. Exceptions can be suffixed with either ``Exception`` (e.g., ``SecurityException``) or |
| ``Error`` (e.g., ``SecurityError``). |
| |
| The recommended method is to declare exception class ``Exception`` or ``Error`` as an |
| inner class, from which the exception is thrown. For example, when declaring class |
| ``Foo`` that can throw errors, one can write the following: |
| |
| .. code-block:: c++ |
| |
| #include <stdexcept> |
| |
| class Foo |
| { |
| class Error : public std::runtime_error |
| { |
| public: |
| explicit |
| Error(const std::string& what) |
| : std::runtime_error(what) |
| { |
| } |
| }; |
| }; |
| |
| In addition to that, if class Foo is a base class or interface for some class |
| hierarchy, then child classes should should define their own ``Error`` or |
| ``Exception`` classes that are inherited from the parent's Error class. |
| |
| |
| 2.25. Functions (methods returning something) should be named after what they return and |
| procedures (void methods) after what they do. |
| |
| Increase readability. Makes it clear what the unit should do and especially all the |
| things it is not supposed to do. This again makes it easier to keep the code clean of |
| side effects. |
| |
| 3. Miscellaneous |
| ---------------- |
| |
| 3.1. Exceptions can be used in the code, but should be used only in exceptional cases and |
| not in the primary processing path. |
| |
| 3.2. Header files must contain an include guard. |
| |
| For example, header file located in ``module/class-name.hpp`` or in |
| ``src/module/class-name.hpp`` should have header guard in the following form: |
| |
| .. code-block:: c++ |
| |
| #ifndef APP_MODULE_CLASS_NAME_HPP |
| #define APP_MODULE_CLASS_NAME_HPP |
| ... |
| #endif // APP_MODULE_CLASS_NAME_HPP |
| |
| The name should follow the location of the file inside the source tree and prevents |
| naming conflicts. Header guard should be prefixed with the application/library name |
| to avoid conflicts with other packaged and libraries. |
| |
| 3.3. Header files which are in the same source distribution should be included in |
| ``"quotes"``, if possible with a path relative to the source file. Header files for |
| system and other external libraries should be included in ``<angle brackets>``. |
| |
| .. code-block:: c++ |
| |
| #include <string> |
| #include <boost/lexical_cast.hpp> |
| |
| #include "util/random.hpp" |
| |
| 3.4. Include statements should be sorted and grouped. Sorted by their hierarchical position |
| in the system with low level files included first. Leave an empty line between groups |
| of include statements. |
| |
| .. code-block:: c++ |
| |
| #include <fstream> |
| #include <iomanip> |
| |
| #include <boost/lexical_cast.hpp> |
| #include <boost/regex.hpp> |
| |
| #include "detail/pending-interest.hpp" |
| #include "util/random.hpp" |
| |
| |
| 3.5. Types that are local to one file only can be declared inside that file. |
| |
| |
| 3.6. Implicit conversion is generally allowed. |
| |
| Implicit conversion between integer and floating point numbers can cause problems and |
| should be avoided. |
| |
| Implicit conversion in single-argument constructor is usually undesirable. Therefore, all |
| single-argument constructors should be marked 'explicit', unless implicit conversion is |
| desirable. In that case, a comment should document the reason. |
| |
| Avoid C-style casts. Use ``static_cast``, ``dynamic_cast``, ``reinterpret_cast``, |
| ``const_cast`` instead where appropriate. Use ``static_pointer_cast``, |
| ``dynamic_pointer_cast``, ``const_pointer_cast`` when dealing with ``shared_ptr``. |
| |
| |
| 3.7. Variables should be initialized where they are declared. |
| |
| This ensures that variables are valid at any time. Sometimes it is impossible to |
| initialize a variable to a valid value where it is declared: |
| |
| .. code-block:: c++ |
| |
| int x, y, z; |
| getCenter(&x, &y, &z); |
| |
| In these cases it should be left uninitialized rather than initialized to some phony |
| value. |
| |
| 3.8. In most cases, class instance variables should not be declared public. |
| |
| The concepts of information hiding and encapsulation are violated by public variables. Use |
| private variables and access methods instead. |
| |
| Exceptions to this rule: |
| |
| * when the class is essentially a dumb data structure with no or minimal behavior |
| (equivalent to a C struct, also known as PODS). In this case it is appropriate to make |
| the instance variables public by using struct. |
| |
| * when the class is used only inside the compilation unit, e.g., when implementing pImpl |
| idiom (aka Bridge pattern) or similar cases. |
| |
| |
| 3.9. C++ pointers and references should have their reference symbol next to the type rather |
| than to the name. |
| |
| .. code-block:: c++ |
| |
| float* x; // NOT: float *x; |
| int& y; // NOT: int &y; |
| |
| 3.10. Implicit test for 0 should not be used other than for boolean variables and pointers. |
| |
| .. code-block:: c++ |
| |
| if (nLines != 0) // NOT: if (nLines) |
| if (value != 0.0) // NOT: if (value) |
| |
| 3.11. When checking if ``shared_ptr`` points to an object, explicit ``static_cast<bool>`` |
| must be used. |
| |
| ``shared_ptr`` in C++11 (unlike ``boost::shared_ptr``) does not have implicit |
| conversion to bool. |
| |
| 3.12. Loop variables should be initialized immediately before the loop. |
| |
| .. code-block:: c++ |
| |
| isDone = false; // NOT: bool isDone = false; |
| while (!isDone) { // // other stuff |
| : // while (!isDone) { |
| } // : |
| // } |
| |
| 3.13. The form while (true) should be used for infinite loops. |
| |
| .. code-block:: c++ |
| |
| while (true) { |
| ... |
| } |
| |
| // NOT: |
| for (;;) { // NO! |
| : |
| } |
| while (1) { // NO! |
| : |
| } |
| |
| 3.14. Complex conditional expressions must be avoided. Introduce temporary boolean variables |
| instead. |
| |
| .. code-block:: c++ |
| |
| bool isFinished = (elementNo < 0) || (elementNo > maxElement); |
| bool isRepeatedEntry = elementNo == lastElement; |
| if (isFinished || isRepeatedEntry) { |
| ... |
| } |
| |
| // NOT: |
| // if ((elementNo < 0) || (elementNo > maxElement) || elementNo == lastElement) { |
| // ... |
| // } |
| |
| By assigning boolean variables to expressions, the program gets automatic |
| documentation. The construction will be easier to read, debug and maintain. |
| |
| 3.15. The conditional should be put on a separate line. |
| |
| .. code-block:: c++ |
| |
| if (isDone) // NOT: if (isDone) doCleanup(); |
| doCleanup(); |
| |
| This is for debugging purposes. When writing on a single line, it is not apparent |
| whether the test is really true or not. |
| |
| 3.16. Assignment statements in conditionals must be avoided. |
| |
| .. code-block:: c++ |
| |
| File* fileHandle = open(fileName, "w"); |
| if (!fileHandle) { |
| ... |
| } |
| |
| // NOT |
| // if (!(fileHandle = open(fileName, "w"))) { |
| // .. |
| // } |
| |
| 3.17. The use of magic numbers in the code should be avoided. Numbers other than 0 and 1 |
| should be considered declared as named constants instead. |
| |
| If the number does not have an obvious meaning by itself, the readability is enhanced |
| by introducing a named constant instead. A different approach is to introduce a method |
| from which the constant can be accessed. |
| |
| 3.18. Floating point constants should always be written with decimal point, at least one |
| decimal, and without omitting 0 before decimal point. |
| |
| .. code-block:: c++ |
| |
| double total = 0.0; // NOT: double total = 0; |
| double someValue = 0.1; // NOT double someValue = .1; |
| double speed = 3.0e8; // NOT: double speed = 3e8; |
| double sum; |
| ... |
| sum = (a + b) * 10.0; |
| |
| 3.19. ``goto`` should not be used. |
| |
| Goto statements violate the idea of structured code. Only in some very few cases (for |
| instance breaking out of deeply nested structures) should goto be considered, and only if |
| the alternative structured counterpart is proven to be less readable. |
| |
| 3.20. "0" should be used instead of "NULL". |
| |
| 3.21. Logical units within a block should be separated by one blank line. |
| |
| .. code-block:: c++ |
| |
| Matrix4x4 matrix = new Matrix4x4(); |
| |
| double cosAngle = Math.cos(angle); |
| double sinAngle = Math.sin(angle); |
| |
| matrix.setElement(1, 1, cosAngle); |
| matrix.setElement(1, 2, sinAngle); |
| matrix.setElement(2, 1, -sinAngle); |
| matrix.setElement(2, 2, cosAngle); |
| |
| multiply(matrix); |
| |
| Enhance readability by introducing white space between logical units of a block. |
| |
| 3.22. Variables in declarations can be left aligned. |
| |
| .. code-block:: c++ |
| |
| AsciiFile* file; |
| int nPoints; |
| float x, y; |
| |
| Enhance readability. The variables are easier to spot from the types by alignment. |
| |
| 3.23. Use alignment wherever it enhances readability. |
| |
| .. code-block:: c++ |
| |
| value = (potential * oilDensity) / constant1 + |
| (depth * waterDensity) / constant2 + |
| (zCoordinateValue * gasDensity) / constant3; |
| |
| minPosition = computeDistance(min, x, y, z); |
| averagePosition = computeDistance(average, x, y, z); |
| |
| There are a number of places in the code where white space can be included to enhance |
| readability even if this violates common guidelines. Many of these cases have to do |
| with code alignment. General guidelines on code alignment are difficult to give, but |
| the examples above should give a general clue. |
| |
| 3.24. All comments should be written in English. |
| |
| In an international environment English is the preferred language. |
| |
| 3.25. Use ``//` for all comments, including multi-line comments. |
| |
| .. code-block:: c++ |
| |
| // Comment spanning |
| // more than one line. |
| |
| Since multilevel C-commenting is not supported, using ``//`` comments ensure that it |
| is always possible to comment out entire sections of a file using ``/* */`` for |
| debugging purposes etc. |
| |
| There should be a space between the ``//`` and the actual comment, and comments should |
| always start with an upper case letter and end with a period. |
| |
| However, method and class documentation comments should use ``/** */`` style for |
| Doxygen, JavaDoc and JSDoc. |
| |
| 3.26. Comments should be included relative to their position in the code. |
| |
| .. code-block:: c++ |
| |
| while (true) { |
| // Do something |
| something(); |
| } |
| |
| // NOT: |
| while (true) { |
| // Do something |
| something(); |
| } |
| |
| This is to avoid that the comments break the logical structure of the program. |