From 8a4550c8f9666212b149f4ba8c3b0f70b44d6e5e Mon Sep 17 00:00:00 2001 From: Thibault Kruse Date: Mon, 5 Oct 2015 14:15:21 +0200 Subject: [PATCH] Minor style issues --- CppCoreGuidelines.md | 80 ++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index f283af7..5d3f273 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -147,7 +147,7 @@ All C++ programmers. This includes [programmers who might consider C](#S-cpl). The purpose of this document is to help developers to adopt modern C++ (C++11, C++14, and soon C++17) and to achieve a more uniform style across code bases. -We do not suffer the delusion that every one of these rules can be effectively applied to every code base. Upgrading old systems is hard. However, we do believe that a program that uses a rule is less error-prone and more maintainable than one that does not. Often, rules also lead to faster/easier initial development. +We do not suffer the delusion that every one of these rules can be effectively applied to every code base. Upgrading old systems is hard. However, we do believe that a program that uses a rule is less error-prone and more maintainable than one that does not. Often, rules also lead to faster/easier initial development. As far as we can tell, these rules lead to code that performs as well or better than older, more conventional techniques; they are meant to follow the zero-overhead principle ("what you don't use, you don't pay for" or "when you use an abstraction mechanism appropriately, you get at least as good performance as if you had handcoded using lower-level language constructs"). Consider these rules ideals for new code, opportunities to exploit when working on older code, and try to approximate these ideas as closely as feasible. Remember: @@ -1083,11 +1083,11 @@ Obviously, we cannot catch all errors through the static type system In the following example, it is not clear from the interface what time_to_blink means: Seconds? Milliseconds? - void blink_led(int time_to_blink) //bad - the unit is ambiguous + void blink_led(int time_to_blink) // bad - the unit is ambiguous { - //... - //do something with time_to_blink - //... + // ... + // do something with time_to_blink + // ... } void use() @@ -1099,11 +1099,11 @@ In the following example, it is not clear from the interface what time_to_blink std::chrono::duration types introduced in C++11 helps making the unit of time duration explicit. - void blink_led(milliseconds time_to_blink) //good - the unit is explicit + void blink_led(milliseconds time_to_blink) // good - the unit is explicit { - //... - //do something with time_to_blink - //... + // ... + // do something with time_to_blink + // ... } void use() @@ -1114,13 +1114,13 @@ std::chrono::duration types introduced in C++11 helps making the unit of time du The function can also be written in such a way that it will accept any time duration unit. template - void blink_led(duration time_to_blink) //good - accepts any unit + void blink_led(duration time_to_blink) // good - accepts any unit { - //assuming that millisecond is the smallest relevant unit + // assuming that millisecond is the smallest relevant unit auto milliseconds_to_blink = duration_cast(time_to_blink); - //... - //do something with milliseconds_to_blink - //... + // ... + // do something with milliseconds_to_blink + // ... } void use() @@ -1770,11 +1770,11 @@ If you write a non-trivial lambda that potentially can be used in more than one ##### Example - sort(a, b, [](T x, T y) { return x.valid() && y.valid() && x.value() - auto square(T t) { return t*t; } + auto square(T t) { return t * t; } ##### Note @@ -3613,9 +3613,9 @@ If the `Handle` owns the object referred to by `s` it must have a destructor. Independently of whether `Handle` owns its `Shape`, we must consider the default copy operations suspect: - Handle x {*new Circle{p1, 17}}; // the Handle had better own the Circle or we have a leak + Handle x {*new Circle{p1, 17}}; // the Handle had better own the Circle or we have a leak Handle y {*new Triangle{p1, p2, p3}}; - x = y; // the default assignment will try *x.s=*y.s + x = y; // the default assignment will try *x.s = *y.s That `x=y` is highly suspect. Assigning a `Triangle` to a `Circle`? @@ -4420,12 +4420,12 @@ After a copy `x` and `y` can be independent objects (value semantics, the way no ##### Example - class X2 { // OK: pointer semantics + class X2 { // OK: pointer semantics public: X2(); - X2(const X&) = default; // shallow copy + X2(const X&) = default; // shallow copy ~X2() = default; - void modify(); // change the value of X + void modify(); // change the value of X // ... private: T* p; @@ -4441,7 +4441,7 @@ After a copy `x` and `y` can be independent objects (value semantics, the way no X2 y = x; if (x != y) throw Bad{}; x.modify(); - if (x != y) throw Bad{}; // assume pointer semantics + if (x != y) throw Bad{}; // assume pointer semantics ##### Note @@ -4577,7 +4577,7 @@ Often, we can easily and cheaply do better: The standard library assumes that it ##### Note -Unless there is an exceptionally strong reason not to, make `x=std::move(y); y=z;` work with the conventional semantics. +Unless there is an exceptionally strong reason not to, make `x = std::move(y); y = z;` work with the conventional semantics. ##### Enforcement @@ -4587,7 +4587,7 @@ Unless there is an exceptionally strong reason not to, make `x=std::move(y); y=z ##### Reason -If `x=x` changes the value of `x`, people will be surprised and bad errors may occur. However, people don't usually directly write a self-assignment that turn into a move, but it can occur. However, `std::swap` is implemented using move operations so if you accidentally do `swap(a, b)` where `a` and `b` refer to the same object, failing to handle self-move could be a serious and subtle error. +If `x = x` changes the value of `x`, people will be surprised and bad errors may occur. However, people don't usually directly write a self-assignment that turn into a move, but it can occur. However, `std::swap` is implemented using move operations so if you accidentally do `swap(a, b)` where `a` and `b` refer to the same object, failing to handle self-move could be a serious and subtle error. ##### Example @@ -4965,7 +4965,10 @@ It is really hard to write a foolproof and useful `==` for a hierarchy. class B { string name; int number; - virtual bool operator==(const B& a) const { return name == a.name && number == a.number; } + virtual bool operator==(const B& a) const + { + return name == a.name && number == a.number; + } // ... }; @@ -4973,7 +4976,10 @@ It is really hard to write a foolproof and useful `==` for a hierarchy. class D :B { char character; - virtual bool operator==(const D& a) const { return name == a.name && number == a.number && character == a.character; } + virtual bool operator==(const D& a) const + { + return name == a.name && number == a.number && character == a.character; + } // ... }; @@ -5267,7 +5273,7 @@ Copying a base is usually slicing. If you really need copy semantics, copy deepl class base { public: - virtual base* clone() =0; + virtual base* clone() = 0; }; class derived : public base { @@ -8415,7 +8421,7 @@ Avoid wrong results. unsigned x = 100; unsigned y = 102; - cout << abs(x-y) << '\n'; //wrong result + cout << abs(x-y) << '\n'; // wrong result ##### Note @@ -8696,14 +8702,14 @@ Performance is very sensitive to cache performance and cache algorithms favor si int matrix[rows][cols]; - //bad - for (int c=0; c PER.30: Avoid context switches on the critical path @@ -13245,7 +13251,7 @@ To simplify code and eliminate a need for explicit memory management. To bring a return ...; } - auto v = get_large_vector(); //return by value is ok, most modern compilers will do copy elision + auto v = get_large_vector(); // return by value is ok, most modern compilers will do copy elision ##### Example