diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-09-25 03:27:09 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-09-25 03:27:09 +0200 |
commit | ce22517f30193f79011f4345b365301a9e6183f5 (patch) | |
tree | 680d9a6cf8f4dadedb1f1708fd431fc54baab464 | |
parent | 8424d71f135b7872fd2db40969758ed7e3c1071c (diff) |
Start C++ style document
-rw-r--r-- | cxx-style.txt | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/cxx-style.txt b/cxx-style.txt new file mode 100644 index 0000000..64af573 --- /dev/null +++ b/cxx-style.txt @@ -0,0 +1,59 @@ +0. Don't try to be clever, prefer value/move semantics + +These days optimizers can often "see through" (via constexpr/inline/lto) and +optimize simple code that uses value semantics to the equivalent (or even +better) "clever" code that tries to avoid extra copies, allocations, etc. + +See also the note on small value optimization. + +1. Almost never auto + +Using auto instead of the actual type often makes code harder to understand. +You may (but don't have to) use auto when (a) the type is spelled out on the +right hand side (e.g., casts, make_*<>() functions, etc), and (b) in cases of +idiomatic use where the type is clear to anyone familiar with C++ and it would +be painful to spell it out explicitly. + +Examples of the latter are lambda initializations, iterator initializations +(e.g, from begin()), and some cases of pair initialization (e.g, from +container's insert()). + +2. Almost never brace-initialization + +We only use brace-initialization syntax when initializing an aggregate or a +container. We can also use it for an aggregate-like initialization of an +aggregate-like class. + +An aggregate-like class is class with public data members only and an +aggregate-like initialization is an initialization that provides initializers +for every such data member. For example: + +struct foo +{ + int x, y; + + foo (int x, int y); + foo (int both); +}; + +foo x {0, 1}; // Ok. +foo x {0}; // Bad. + +For default member variable initialization use assignment syntax, for example: + +struct foo +{ + int i = 123; + string s = string (123, 's'); +}; + +3. Many performance-critical standard types are "small object optimized" + +For example, across all the implementations that we care, std::string can hold +at least 15 characters without allocation. Similarly, std::function can hold a +lambda with at least 2 pointers also without allocation. + +As a result, it is seldom makes sense to resort to elaborate optimizations +such as string pooling. In fact, if we have a string pool that contains mostly +short, SOO strings, then we will most likely hurt performance due to lack of +locality. |