Merge branch 'flippingtables-master'

This commit is contained in:
Andrew Pardoe 2015-09-20 09:24:39 -07:00
commit a672faaad8

View File

@ -842,7 +842,7 @@ Alternatively, mark an owner as such using `owner` from [the GSL](#S-support).
// ...
}
Yes, this is a carricature, but we have seen every individual mistake in production code, and worse.
Yes, this is a caricature, but we have seen every individual mistake in production code, and worse.
Note that the layout of `X` guarantees that at least 6 bytes (and most likely more) bytes are wasted.
The spurious definition of copy operations disables move semantics so that the return operation is slow.
The use of `new` and `delete` for `buf` is redundant; if we really needed a local string, we should use a local `string`.
@ -996,7 +996,7 @@ That's part of the problem.
This one of the most effective solution to problem related to initialization order.
In a multi-threaded environment the initialization of the static object does not introduce a race condition
(unless you carelessly access a shared objects from within its consructor).
(unless you carelessly access a shared objects from within its constructor).
If you, as many do, define a singleton as a class for which only one object is created, functions like `myX` are not singletons,
and this useful technique is not an exception to the no-singleton rule.
@ -1514,7 +1514,7 @@ This will force every derived class to compute a center -- even if that's non-tr
**Exception**: You can carefully craft an interface using a few carefully selected higher-level C++ types. See ???.
**Exception**: Common ABIs are emerging on some platfoms freeing you from the more Draconian restrictions.
**Exception**: Common ABIs are emerging on some platforms freeing you from the more Draconian restrictions.
**Note**: if you use a single compiler, you can use full C++ in interfaces. That may require recompilation after an upgrade to a new compiler version.
@ -1603,7 +1603,7 @@ If something is a well-specified action, separate it out from its surrounding c
Almost everything is wrong with `read_and_print`.
It reads, it writes (to a fixed `ostream`), it write error messages (to a fixed `ostream`), it handles only `int`s.
There is nothing to reuse, logically separate operations are intermingled and local variables are in scope after the end of their logical use.
For a tiny example, this looks OK, but if the input opeartion, the output operation, and the error handling had been more complicated the tangled
For a tiny example, this looks OK, but if the input operation, the output operation, and the error handling had been more complicated the tangled
mess could become hard to understand.
**Note**: If you write a non-trivial lambda that potentially can be used in more than one place,
@ -1695,7 +1695,7 @@ If there was a need, we could further templatize `read()` and `print()` on the d
### F.3: Keep functions short and simple
**Reason**: Large functions are hard to read, more likely to contain complex code, and more likely to have variables in larger than minimal scopes.
Functions with complex control stryuctures are more likely to be long and more likely to hide logical errors
Functions with complex control structures are more likely to be long and more likely to hide logical errors
**Example**: Consider
@ -1809,7 +1809,7 @@ This is usually a very good thing.
**Note**: Don't try to make all functions `constexpr`. Most computation is best done at run time.
**Enforcement**: Imposible and unnecessary.
**Enforcement**: Impossible and unnecessary.
The compiler gives an error if a non-`constexpr` function is called where a constant is required.
@ -2389,12 +2389,12 @@ This applies to references as well:
{
int x = 7;
// ...
return x; // Bad: returns refence to object that is about to be destroyed
return x; // Bad: returns reference to object that is about to be destroyed
}
**See also**: [discussion of dangling pointer prevention](#???).
**Enforcement**: A slightly diffent variant of the problem is placing pointers in a container that outlives the objects pointed to.
**Enforcement**: A slightly different variant of the problem is placing pointers in a container that outlives the objects pointed to.
* Compilers tend to catch return of reference to locals and could in many cases catch return of pointers to locals.
* Static analysis can catch most (all?) common patterns of the use of pointers indicating positions (thus eliminating dangling pointers)
@ -2716,7 +2716,7 @@ but
For example, we can now change the representation of a `Date` without affecting its users (recompilation is likely, though).
**Note**: Using a class in this way to represent the distinction between interface and implementation is of course not the only way.
For example, we can use a set of declarations of freestandanding functions in a namespace,
For example, we can use a set of declarations of freestanding functions in a namespace,
an abstract base class,
or a template fuction with concepts to represent an interface.
The most important issue is to explicitly distinguish between an interface and its implementation "details."
@ -2837,7 +2837,7 @@ You need a reason (use cases) for using a hierarchy.
}
If a class can be part of a hierarchy, we (in real code if not necessarily in small examples) must manipulate its objects through pointers or references.
That implies more memory overhead, more allocations and deallocations, and more run-time overhead to perform the resulting indiretions.
That implies more memory overhead, more allocations and deallocations, and more run-time overhead to perform the resulting indirections.
**Note**: Concrete types can be stack allocated and be members of other classes.
@ -3297,7 +3297,7 @@ Assigning a `Triangle` to a `Circle`?
Unless `Shape` has its [copy assignment `=deleted`](#Rc-copy-virtual), only the `Shape` part of `Triangle` is copied into the `Circle`.
**Note**: Why not just require all owning refereces to be replaced by "smart pointers"?
**Note**: Why not just require all owning references to be replaced by "smart pointers"?
Changing from references to smart pointers implies code changes.
We don't (yet) have smart references.
Also, that may affect ABIs.
@ -3795,7 +3795,7 @@ How would a maintainer know whether `j` was deliberately uninitialized (probably
class B { // BAD
string s1;
public:
B() { s1 = "Hello, "; } // BAD: default constuct followed by assignment
B() { s1 = "Hello, "; } // BAD: default constructor followed by assignment
// ...
};
@ -3874,7 +3874,7 @@ By providing the factory function `Create()`, we make construction (on the free
**Example; bad**:
class Date { // BAD: repettive
class Date { // BAD: repetitive
int d;
Month m;
int y;
@ -5279,7 +5279,7 @@ The two operations are still fundamentally different (and unrelated) but the nam
**Reason**: Implicit conversions can be essential (e.g., `double` to '`int`) but often cause surprises (e.g., `String` to C-style string).
**Note**: Prefer explicitly named conversions until a serious need is demonstracted.
**Note**: Prefer explicitly named conversions until a serious need is demonstrated.
By "serious need" we mean a reason that is fundamental in the application domain (such as an integer to complex number conversion)
and frequently needed. Do not introduce implicit conversions (through conversion operators or non-`explicit` constructors)
just to gain a minor convenience.
@ -5862,7 +5862,7 @@ The use of the file handle (in `ifstream`) is simple, efficient, and safe.
**Enforcement**:
* Flag explicit allocations used to initialize pointers (problem: how many direct resouce allocations can we recognize?)
* Flag explicit allocations used to initialize pointers (problem: how many direct resource allocations can we recognize?)
<a name ="Rr-single alloc"></a>
@ -5898,7 +5898,7 @@ Write your own factory wrapper if there is not one already.
**Enforcement**:
* Flag expressions with multiple explicit resource allocations (problem: how many direct resouce allocations can we recognize?)
* Flag expressions with multiple explicit resource allocations (problem: how many direct resource allocations can we recognize?)
<a name ="Rr-ap"></a>
@ -6576,7 +6576,7 @@ We recommend keeping functions short, but that rule isn't universally adhered to
<a name="Res-!CAPS"></a>
### ES.9: Avoid `ALL_CAPS` names
**Reason**: Such names are commonly used for macros. Thus, ALL_CAPS name are vulnarable to unintend macro substitution.
**Reason**: Such names are commonly used for macros. Thus, ALL_CAPS name are vulnerable to unintended macro substitution.
**Example**:
@ -7169,7 +7169,7 @@ rather than
cout << v[i] << '\n';
}
A human or a good static analyzer may determine that there really isn't a side efect on `v` in `f(&v[i])` so that the loop can be rewritten.
A human or a good static analyzer may determine that there really isn't a side effect on `v` in `f(&v[i])` so that the loop can be rewritten.
"Messing with the loop variable" in the body of a loop is typically best avoided.
@ -7355,7 +7355,7 @@ Expressions manipulate values.
x = a+(b=f())+(c=g())*7; // bad: multiple assignments "hidden" in subexpressions
x = a&b+c*d&&e^f==7; // bad: relies on commonly misunderstool precedence rules
x = a&b+c*d&&e^f==7; // bad: relies on commonly misunderstood precedence rules
x = x++ + x++ + ++x; // bad: undefined behavior
@ -7379,7 +7379,7 @@ Some of these expressions are unconditionally bad (e.g., they rely on undefined
**Enforcement**: Tricky. How complicated must an expression be to be considered complicated? Writing computations as statements with one operation each is also confusing. Things to consider:
* sideffects: sideffects on multiple non-local variables (for some definition of non-local) can be suspect, expecially if the sideefects are in separate subexpressions
* side effects: side effects on multiple non-local variables (for some definition of non-local) can be suspect, especially if the side effects are in separate subexpressions
* writes to aliased variables
* more than N operators (and what should N be?)
* reliance of subtle precedence rules
@ -7545,7 +7545,7 @@ We also include lossy arithmetic casts, such as from a negative floating point t
<a name="Res-nullptr"></a>
### ES.47: Use `nullptr` rather than `0` or `NULL`
**Reason**: Readibility. Minimize surprises: `nullptr` cannot be confused with an `int`.
**Reason**: Readability. Minimize surprises: `nullptr` cannot be confused with an `int`.
**Example**: Consider
@ -7629,7 +7629,7 @@ Such examples are often handled as well or better using `mutable` or an indirect
<a name="Res-range-checking"></a>
### ES.55: Avoid the need for range checking
**Reason**: Constructs that cannot oveflow, don't, and usually runs faster:
**Reason**: Constructs that cannot overflow, don't, and usually runs faster:
**Example**:
@ -7721,7 +7721,7 @@ There can be code in the `...` part that causes the `delete` never to happen.
**Note** Unfortunately, C++ uses signed integers for array subscripts and the standard library uses unsigned integers for container subscripts.
This precludes consistency.
**Enforcement**: Complilers already know and sometimes warn.
**Enforcement**: Compilers already know and sometimes warn.
<a name="Res-unsigned"></a>
@ -8243,7 +8243,7 @@ and to recover from an error every object not destroyed must be in a valid state
<a name="Re-invariant"></a>
### E.5: Let a constructor establish an invariant, and throw if it cannot
**Reason**: Leaving an object without its invariant aestablished is asking for trouble.
**Reason**: Leaving an object without its invariant established is asking for trouble.
Not all member function can be called.
**Example**:
@ -8570,7 +8570,7 @@ Let cleanup actions on the unwinding path be handles by [RAII](#Re-raii).
// ...
}
catch (...) {
throw; // propagate excption
throw; // propagate exception
}
}
@ -8720,7 +8720,7 @@ Concept use rule summary:
* [T.10: Specify concepts for all template arguments](#Rt-concepts)
* [T.11: Whenever possible use standard concepts](#Rt-std)
* [T.12: Prefer concept names over `auto` for local variables](#Rt-auto)
* [T.13: Prefer the shorhand notation for simple, single-type agument concepts](#Rt-shorthand)
* [T.13: Prefer the shorthand notation for simple, single-type argument concepts](#Rt-shorthand)
* ???
Concept definition rule summary:
@ -8974,7 +8974,7 @@ Concept use rule summary:
* [T.10: Specify concepts for all template arguments](#Rt-concepts)
* [T.11: Whenever possible use standard concepts](#Rt-std)
* [T.14: Prefer concept names over `auto`](#Rt-auto)
* [T.15: Prefer the shorhand notation for simple, single-type agument concepts](Rt-shorthand)
* [T.15: Prefer the shorthand notation for simple, single-type argument concepts](Rt-shorthand)
* ???
Concept definition rule summary:
@ -9041,7 +9041,7 @@ This is typically only needed when (as part of template metaprogramming code) we
<a name="Rt-std"></a>
### T.11: Whenever possible use standard concepts
**Reason**: "Standard" concepts (as provideded by the GSL, the ISO concepts TS, and hopefully soon the ISO standard itself)
**Reason**: "Standard" concepts (as provided by the GSL, the ISO concepts TS, and hopefully soon the ISO standard itself)
saves us the work of thinking up our own concepts, are better thought out than we can manage to do in a hurry, and improves interoperability.
**Note**: Unless you are creating a new generic library, most of the concepts you need will already be defined by the standard library.
@ -9086,7 +9086,7 @@ It is better and simpler just to use `Sortable`:
<a name="Rt-shorthand"></a>
### T.13: Prefer the shorhand notation for simple, single-type agument concepts
### T.13: Prefer the shorthand notation for simple, single-type argument concepts
**Reason**: Readability. Direct expression of an idea.
@ -9457,7 +9457,7 @@ Uniformity: `using` is syntactically similar to `auto`.
tuple<int,string,double> t1 = {1,"Hamlet",3.14}; // explicit type
auto t2 = make_tuple(1,"Ophelia"s,3.14); // better; deduced type
Note the use of the `s` suffix to ensire that the string is a `std::string`, rather than a C-style string.
Note the use of the `s` suffix to ensure that the string is a `std::string`, rather than a C-style string.
**Note**: Since you can trivially write a `make_T` function, so could the compiler. Thus, `make_T` functions may become redundant in the future.
@ -9726,7 +9726,7 @@ There are three major ways to let calling code customize a template.
f(t); // require f(/*T*/) be available in caller's cope or in T's namespace
}
* Invoke a "trait" -- usually a type alias to compute a type, or a `constexpr` function to compute a value, or in rarer cases a traditioal traits template to be specialized on the user's type.
* Invoke a "trait" -- usually a type alias to compute a type, or a `constexpr` function to compute a value, or in rarer cases a traditional traits template to be specialized on the user's type.
template<class T>
void test(T t) {
@ -10202,7 +10202,7 @@ Of course, range-for is better still where it does what you want.
<a name="Rt-specialize-function"></a>
### T.144: Don't specialize function templates
**Reason**: You can't partially specialize a function template per language rules. You can fully specialize a function tempalte but you almost certainly want to overload instead -- because function template specializations don't participate in overloading, they don't act as you probably wanted. Rarely, you should actualy specialize by delegating to a class template that you can specialize properly.
**Reason**: You can't partially specialize a function template per language rules. You can fully specialize a function template but you almost certainly want to overload instead -- because function template specializations don't participate in overloading, they don't act as you probably wanted. Rarely, you should actually specialize by delegating to a class template that you can specialize properly.
**Example**:
@ -10211,7 +10211,7 @@ Of course, range-for is better still where it does what you want.
**Exceptions**: If you do have a valid reason to specialize a function template, just write a single function template that delegates to a class template, then specialize the class template (including the ability to write partial specializations).
**Enforcement**:
* Flag all specializations of a funciton template. Overload instead.
* Flag all specializations of a function template. Overload instead.
@ -10675,7 +10675,7 @@ Many
* focus on lower-level issues, such as the spelling of identifiers
* are written by C++ novices
* see "stopping programmers from doing unusual things" as their primary aim
* aim at protability across many compilers (some 10 years old)
* aim at portability across many compilers (some 10 years old)
* are written to preserve decades old code bases
* aims at a single application domain
* are downright counterproductive
@ -11468,7 +11468,7 @@ Comments are not updates as consistently as code.
auto x = m*v1 + vv; // multiply m with v1 and add the result to vv
**Enforcement**: Build an AI program that interprets colloqual English text and see if what is said could be better expressed in C++.
**Enforcement**: Build an AI program that interprets colloquial English text and see if what is said could be better expressed in C++.
<a name="Rl-comments intent"></a>
@ -11651,7 +11651,7 @@ If you prefer CamelCase, you have to choose among different flavors of camelCase
// ...
}
**Note**: Some IDEs have their own opinios and adds distracting space.
**Note**: Some IDEs have their own opinions and adds distracting space.
**Note**: We value well-placed whitespace as a significant help for readability. Just don't overdo it.
@ -11798,7 +11798,7 @@ In most circumstances, it is also impossible.
This would be a set of changes across the whole code base, but would most likely have huge benefits.
Whichever way you choose, please note that the most advantages come with the highest conformance to the guidelines.
The guidelines are not a random set of unrelated rules where you can srandomly pick and choose with an expectation of success.
The guidelines are not a random set of unrelated rules where you can randomly pick and choose with an expectation of success.
We would dearly love to hear about experience and about tools used.
Modernization can be much faster, simpler, and safer when supported with analysis tools and even code transformation tools.