- First column = Guildeline name = Link to the rule in the master branch of the Git repository of CppCoreGuidelines
- Second column = Summary (one short line)
- If you do not understand the Summary => Spend more time reading the rule
- If you think the Summary can be improved => Please edit this file :-)
- If the Summary is ”???” => There is not (yet) a summary => Please provide a summary :-)
- Third column = Acceptation = Position of developers (Yes, Yes but…, Optional, No because…, No way)
Guildeline name | Summary | Acceptation
——————–|————————-|——————————–
P.1: Express ideas directly in code | Replace anonymous int
by functional EventID
| Yes
P.2: Write in ISO Standard C++ | No Visual/GNU C++ extensions | Yes
P.3: Express intent | Code for the other devs, Self-explanatory code does not need comments | Yes
P.4: Ideally, a program should be statically type safe | Replace union
-> variant
and int array[5]
-> span
| Yes
P.5: Prefer compile-time checking to run-time checking | Replace assert
by static_assert
when possible | Yes
P.6: What cannot be checked at compile time should be checkable at run time | Use span
| Developer decides, reviewer may propose to use span
P.7: Catch run-time errors early | ??? (please provide a summary) | Yes
P.8: Don’t leak any resources | Use RAII| Yes
P.9: Don’t waste time or space | C++ => Do not sacrify performance | Yes
P.10: Prefer immutable data to mutable data | Use constants when possible (see section Constants and Immutability) | Ok
I.1: Make interfaces explicit | Names (of function/variable…) must convey semantic (no surprise when used) | Yes
I.2 Avoid global variables | Global variable hide dependencies (except const
). Put log level in an object. | Yes but except specific cases (justify)
I.3: Avoid singletons | Singleton is a global variable => Singleton also hides dependencies | Yes but as above (see Dependency Inversion)
I.4: Make interfaces precisely and strongly typed | No anonymous int
or void*
(no error-prone casting). Use instead variant
, base class, template (and C++17 Concept). | Yes. Use setter (SBE) instead of many default arg.
I.5: State preconditions (if any) | Provide comments for preconditions and use Expects()
, static_assert()
, assert()
, if()
…| Yes
I.6: Prefer Expects() for expressing preconditions | Expects()
= Make it clear + Enable analysis tools | No Expects()
on release => assert() static_assert()
. Integrity check => if()
I.7: State postconditions | Same as for preconditions | Yes
I.8: Prefer Ensures() for expressing postconditions | Same as for preconditions | No, same remark as I.6
I.9: If an interface is a template, document its parameters using concepts | Use C++17 Concepts (available in gcc-6.1). In comments if not yet supported. | No, Document in Doxygen if not supported yes)
I.10: Use exceptions to signal a failure to perform a required task | Prevent error silence because system may become unexpected => Throw exception or return error status (or a pair {result + error}). Exceptions in framework. Logs in application | Yes
I.11: Never transfer ownership by a raw pointer (T)](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i11-never-transfer-ownership-by-a-raw-pointer-t) | Avoid ownnership transfer. => Use smart_pointer(unique_ptr or shared_ptr) to pass ownership. => Use owner(GSL) in older code. | Yes
[I.12: Declare a pointer that must not be null as not_null](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i12-declare-a-pointer-that-must-not-be-null-as-not_null) | To avoid nullptr deferencing errors and redundant checks for nullptr. | Yes
[I.13: Do not pass an array as a single pointer](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i13-do-not-pass-an-array-as-a-single-pointer) | Use span and string_span to avoid range error | Developer decides, reviewer may propose to use span
[I.22: Avoid complex initialization of global objects](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i22-avoid-complex-initialization-of-global-objects) | Avoid globals(namespace scope) object altogether | Yes
[I.23: Keep the number of function arguments low](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i23-keep-the-number-of-function-arguments-low) | Avoid more than 8 arguments. Group arguments into meaningfull objects or use default arguments | Yes
[I.24: Avoid adjacent unrelated parameters of the same type](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i24-avoid-adjacent-unrelated-parameters-of-the-same-type) | Pass object representing a range (span). Define struct as parameter type | Yes
[I.25: Prefer abstract classes as interfaces to class hierarchies](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i25-prefer-abstract-classes-as-interfaces-to-class-hierarchies) | Use abstract class with pure virtual function | Yes
[I.26: If you want a cross-compiler ABI, use a C-style subset](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i26-if-you-want-a-cross-compiler-abi-use-a-c-style-subset) | Different compilers implement different binary layouts | Not concerned
[F.1: “Package” meaningful operations as carefully named functions](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f1-package-meaningful-operations-as-carefully-named-functions) | functions can be easier to reuse than objects | Yes
[F.2: A function should perform a single logical operation](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f2-a-function-should-perform-a-single-logical-operation) | simpler to understand, test and reuse | Yes
[F.4: If a function may have to be evaluated at compile time, declare it constexpr](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f4-if-a-function-may-have-to-be-evaluated-at-compile-time-declare-it-constexpr) | contexpr is needed to tell the compiler to allow compile-time evaluation | Yes
[F.18: For “consume” parameters, pass by X&& and std::move the parameter](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f18-for-consume-parameters-pass-by-x-and-stdmove-the-parameter) | avoids a deep copy and sometimes a copy would not have been possible (for ex. std::ofstream) | Yes
[F.60: Prefer T over T& when “no argument” is a valid option | A pointer (T) can be a nullptr and a reference (T&) cannot | Yes
[F.42: Return a T to indicate a position (only)] (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f42-return-a-t-to-indicate-a-position-only) | That’s what pointers are good for. Returning a T* to transfer ownership is a misuse | Yes
[F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms] (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f52-prefer-capturing-by-reference-in-lambdas-that-will-be-used-locally-including-passed-to-algorithms) | know capture options | Yes
F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const | Same semantics for both, better performances | Yes
F.21: To return multiple “out” values, prefer returning a tuple or struct | It is self documenting, and std::ignore can be sued | To bench
[F.26: Use a unique_ptr to transfer ownership where a pointer is needed](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f26-use-a-unique_ptrt-to-transfer-ownership-where-a-pointer-is-needed) | Use std::unique_ptr to ransfer ownership | Yes if code is C++11 only
[F.43: Never (directly or indirectly) return a pointer to a local object](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f43-never-directly-or-indirectly-return-a-pointer-to-a-local-object) | Do not return pointers to local object | Yes
[F.44: Return a T& when copy is undesirable and "returning no object" isn't needed](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f44-return-a-t-when-copy-is-undesirable-and-returning-no-object-isnt-needed) | Return T& when copy is undesirable | Yes
[F.45: Don't return a T&&](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f45-dont-return-a-t) | Do not return T&&, it makes no sense | Yes
[F.46: int is the return type for main()](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f46-int-is-the-return-type-for-main) | void main() is not C++ | Yes
[F.47: Return T& from assignment operators](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f47-return-t-from-assignment-operators) | Ensures consistency with std | Yes
[F.50: Use a lambda when a function won't do (to capture local variables, or to write a local function)](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f50-use-a-lambda-when-a-function-wont-do-to-capture-local-variables-or-to-write-a-local-function) | Same as a function object but more simple to write | Yes
[F.51: Where there is a choice, prefer default arguments over overloading](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f51-where-there-is-a-choice-prefer-default-arguments-over-overloading) | Limits code duplication and behavior divergence | No
[F.53: Avoid capturing by reference in lambdas that will be used nonlocally, including returned, stored on the heap, or passed to another thread](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f53-avoid-capturing-by-reference-in-lambdas-that-will-be-used-nonlocally-including-returned-stored-on-the-heap-or-passed-to-another-thread) | To maintain proper lifecycle | Yes
[F.54: If you capture this, capture all variables explicitly (no default capture)](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f54-if-you-capture-this-capture-all-variables-explicitly-no-default-capture) | Default capture does no behave the same for local variable and data members | To bench
[C.1: Organize related data into structures (structs or classes)](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c1-organize-related-data-into-structures-structs-or-classes) | Ex: x and y i n a class "Point" | OK
[C.2: Use class if the class has an invariant; use struct if the data members can vary independently](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c2-use-class-if-the-class-has-an-invariant-use-struct-if-the-data-members-can-vary-independently) | Readability, hints at invariants | OK
[C.3: Represent the distinction between an interface and an implementation using a class](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c3-represent-the-distinction-between-an-interface-and-an-implementation-using-a-class) | ??? | Ok on principle
[C.4: Make a function a member only if it needs direct access to the representation of a class](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c4-make-a-function-a-member-only-if-it-needs-direct-access-to-the-representation-of-a-class) | Free function should not be tied to a class for no reason | OK
[C.5: Place helper functions in the same namespace as the class they support](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c5-place-helper-functions-in-the-same-namespace-as-the-class-they-support) | Profit from argument dependent lookup | OK
[C.7: Don't define a class or enum and declare a variable of its type in the same statement](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c7-dont-define-a-class-or-enum-and-declare-a-variable-of-its-type-in-the-same-statement) | Useless and confusing for readers | OK
[C.8: use class rather that struct if any member is non-public](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c8-use-class-rather-that-struct-if-any-member-is-non-public) | Hint readers | OK
[C.9: minimize exposure of members](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c9-minimize-exposure-of-members) | Improves encapsulation | OK
[C.10 Prefer a concrete type over more complicated classes](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c10-prefer-a-concrete-type-over-more-complicated-classes) | More simple than a class hierarchy | Unclear
[C.11: Make concrete types regular](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c11-make-concrete-types-regular) | Thats is, behave with a value semantics. Easier to use. | Unclear
[C.20: If you can avoid defining default operations, do](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c20-if-you-can-avoid-defining-default-operations-do) | Shorter code | Yes, and do not reimplement defaults
[C.21: If you define or =delete any default operation, define or =delete them all](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all) | To ensure proper semantics are used | Yes
[C.22: Make default operations consistent](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c22-make-default-operations-consistent) | Doing otherwise would be most confusing | Yes
[C.30: Define a destructor if a class needs an explicit action at object destruction](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c30-define-a-destructor-if-a-class-needs-an-explicit-action-at-object-destruction) | When something must be done at destruction, the destructor must do it | Yes
[C.31: All resources acquired by a class must be released by the class's destructor](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c31-all-resources-acquired-by-a-class-must-be-released-by-the-classs-destructor) | Basis of RAII | Yes
[C.32: If a class has a raw pointer (T*) or reference (T&), consider whether it might be owning](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c32-if-a-class-has-a-raw-pointer-t-or-reference-t-consider-whether-it-might-be-owning) | Annotate pointer as owning or not | OK but avoid owning reference
[C.33: If a class has an owning pointer member, define a destructor](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c33-if-a-class-has-an-owning-pointer-member-define-a-destructor) | If using pointers as members, protect from leak/copy | OK
[C.34: If a class has an owning reference member, define a destructor](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c34-if-a-class-has-an-owning-reference-member-define-a-destructor) | Same as for pointer | Prefer avoid owning reference, else Yes
[C.35: A base class destructor should be either public and virtual, or protected and nonvirtual](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-nonvirtual) | Avoid leak of derived classes members | Prefer avoid owning reference, else Yes
[C.36: A destructor may not fail](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c36-a-destructor-may-not-fail) | RAII safe | OK
[C.37: Make destructors noexcept](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c37-make-destructors-noexcept) | Be explicit on exception absence | OK
[C.40: Define a constructor if a class has an invariant](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c40-define-a-constructor-if-a-class-has-an-invariant) | In Out principle | OK
[C.41: A constructor should create a fully initialized object](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c41-a-constructor-should-create-a-fully-initialized-object) | Be safe with invariant and public interface | OK
[C.42: If a constructor cannot construct a valid object, throw an exception](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c42-if-a-constructor-cannot-construct-a-valid-object-throw-an-exception) | Avoid objects in crashed state | OK
[C.43: Ensure that a class has a default constructor](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c43-ensure-that-a-class-has-a-default-constructor) | Allow default object whenever possible | For value classes
[C.44: Prefer default constructors to be simple and non-throwing](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c44-prefer-default-constructors-to-be-simple-and-non-throwing) | Be safe with default constructors | OK
[C.45: Don't define a default constructor that only initializes data members; use in-class member initializers instead](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead) | Less code better | OK
[C.46: By default, declare single-argument constructors explicit](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c46-by-default-declare-single-argument-constructors-explicit) | Avoid false conversions | OK
[C.47: Define and initialize member variables in the order of member declaration](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c47-define-and-initialize-member-variables-in-the-order-of-member-declaration) | Respect members order | OK