Merge pull request #586 from tkruse/style-fix25

Style fixes
This commit is contained in:
Andrew Pardoe
2016-04-18 06:55:56 -07:00
2 changed files with 206 additions and 182 deletions

View File

@@ -560,7 +560,7 @@ Code clarity and performance. You don't need to write error handlers for errors
static_assert(sizeof(Int) >= 4); // do: compile-time check static_assert(sizeof(Int) >= 4); // do: compile-time check
int bits = 0; // don't: avoidable code int bits = 0; // don't: avoidable code
for (Int i = 1; i; i <<= 1) for (int i = 1; i; i <<= 1)
++bits; ++bits;
if (bits < 32) if (bits < 32)
cerr << "Int too small\n"; cerr << "Int too small\n";
@@ -595,7 +595,8 @@ Ideally we catch all errors (that are not errors in the programmer's logic) at e
##### Example, bad ##### Example, bad
extern void f(int* p); // separately compiled, possibly dynamically loaded // separately compiled, possibly dynamically loaded
extern void f(int* p);
void g(int n) void g(int n)
{ {
@@ -608,11 +609,12 @@ Here, a crucial bit of information (the number of elements) has been so thorough
We can of course pass the number of elements along with the pointer: We can of course pass the number of elements along with the pointer:
extern void f2(int* p, int n); // separately compiled, possibly dynamically loaded // separately compiled, possibly dynamically loaded
extern void f2(int* p, int n);
void g2(int n) void g2(int n)
{ {
f2(new int[n], m); // bad: the wrong number of elements can be passed to f() f2(new int[n], m); // bad: a wrong number of elements can be passed to f()
} }
Passing the number of elements as an argument is better (and far more common) than just passing the pointer and relying on some (unstated) convention for knowing or discovering the number of elements. However (as shown), a simple typo can introduce a serious error. The connection between the two arguments of `f2()` is conventional, rather than explicit. Passing the number of elements as an argument is better (and far more common) than just passing the pointer and relying on some (unstated) convention for knowing or discovering the number of elements. However (as shown), a simple typo can introduce a serious error. The connection between the two arguments of `f2()` is conventional, rather than explicit.
@@ -1000,7 +1002,8 @@ The use of a non-local control is potentially confusing, but controls only imple
Reporting through non-local variables (e.g., `errno`) is easily ignored. For example: Reporting through non-local variables (e.g., `errno`) is easily ignored. For example:
fprintf(connection, "logging: %d %d %d\n", x, y, s); // don't: no test of printf's return value // don't: no test of printf's return value
fprintf(connection, "logging: %d %d %d\n", x, y, s);
What if the connection goes down so that no logging output is produced? See I.??. What if the connection goes down so that no logging output is produced? See I.??.
@@ -1439,7 +1442,8 @@ This is a major source of errors.
int printf(const char* ...); // bad: return negative number if output fails int printf(const char* ...); // bad: return negative number if output fails
template <class F, class ...Args> template <class F, class ...Args>
explicit thread(F&& f, Args&&... args); // good: throw system_error if unable to start the new thread // good: throw system_error if unable to start the new thread
explicit thread(F&& f, Args&&... args);
##### Note: What is an error? ##### Note: What is an error?
@@ -1993,7 +1997,8 @@ Functions with complex control structures are more likely to be long and more li
Consider: Consider:
double simpleFunc(double val, int flag1, int flag2) double simpleFunc(double val, int flag1, int flag2)
// simpleFunc: takes a value and calculates the expected ASIC output, given the two mode flags. // simpleFunc: takes a value and calculates the expected ASIC output,
// given the two mode flags.
{ {
double intermediate; double intermediate;
@@ -2036,12 +2041,14 @@ We can refactor:
} }
double simpleFunc(double val, int flag1, int flag2) double simpleFunc(double val, int flag1, int flag2)
// simpleFunc: takes a value and calculates the expected ASIC output, given the two mode flags. // simpleFunc: takes a value and calculates the expected ASIC output,
// given the two mode flags.
{ {
if (flag1 > 0) if (flag1 > 0)
return func1_muon(val, flag2); return func1_muon(val, flag2);
if (flag1 == -1) if (flag1 == -1)
return func1_tau(-val, flag1, flag2); // handled by func1_tau: flag1 = -flag1; // handled by func1_tau: flag1 = -flag1;
return func1_tau(-val, flag1, flag2);
return 0.; return 0.;
} }
@@ -2308,13 +2315,13 @@ When copying is cheap, nothing beats the simplicity and safety of copying, and f
##### Example ##### Example
void fct(const string& s); // OK: pass by reference to const; always cheap void f(const string& s); // OK: pass by reference to const; always cheap
void fct2(string s); // bad: potentially expensive void f2(string s); // bad: potentially expensive
void fct(int x); // OK: Unbeatable void f3(int x); // OK: Unbeatable
void fct2(const int& x); // bad: overhead on access in fct2() void f4(const int& x); // bad: overhead on access in f4()
For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters: For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:
@@ -2327,7 +2334,8 @@ For advanced uses (only), where you really need to optimize for rvalues passed t
int multiply(int, int); // just input ints, pass by value int multiply(int, int); // just input ints, pass by value
string& concatenate(string&, const string& suffix); // suffix is input-only but not as cheap as an int, pass by const& // suffix is input-only but not as cheap as an int, pass by const&
string& concatenate(string&, const string& suffix);
void sink(unique_ptr<widget>); // input only, and consumes the widget void sink(unique_ptr<widget>); // input only, and consumes the widget
@@ -3076,7 +3084,8 @@ Functions can't capture local variables or be declared at local scope; if you ne
##### Example ##### Example
// writing a function that should only take an int or a string -- overloading is natural // writing a function that should only take an int or a string
// -- overloading is natural
void f(int); void f(int);
void f(const string&); void f(const string&);
@@ -3303,12 +3312,14 @@ but:
class Date { class Date {
public: public:
Date(int yy, Month mm, char dd); // validate that {yy, mm, dd} is a valid date and initialize // validate that {yy, mm, dd} is a valid date and initialize
Date(int yy, Month mm, char dd);
// ... // ...
private: private:
int y; int y;
Month m; Month m;
char d; // day char d; // day
Date(int yy, Month mm, char dd);
}; };
##### Note ##### Note
@@ -3338,7 +3349,8 @@ An explicit distinction between interface and implementation improves readabilit
// ... some representation ... // ... some representation ...
public: public:
Date(); Date();
Date(int yy, Month mm, char dd); // validate that {yy, mm, dd} is a valid date and initialize // validate that {yy, mm, dd} is a valid date and initialize
Date(int yy, Month mm, char dd);
int day() const; int day() const;
Month month() const; Month month() const;
@@ -3565,7 +3577,10 @@ Regular types are easier to understand and reason about than types that are not
vector<Record> vr; vector<Record> vr;
}; };
bool operator==(const Bundle& a, const Bundle& b) { return a.name == b.name && a.vr == b.vr; } bool operator==(const Bundle& a, const Bundle& b)
{
return a.name == b.name && a.vr == b.vr;
}
Bundle b1 { "my bundle", {r1, r2, r3}}; Bundle b1 { "my bundle", {r1, r2, r3}};
Bundle b2 = b1; Bundle b2 = b1;
@@ -7259,7 +7274,7 @@ The members of a scoped object are themselves scoped and the scoped object's con
The following example is inefficient (because it has unnecessary allocation and deallocation), vulnerable to exception throws and returns in the "¦ part (leading to leaks), and verbose: The following example is inefficient (because it has unnecessary allocation and deallocation), vulnerable to exception throws and returns in the "¦ part (leading to leaks), and verbose:
void some_function(int n) void f(int n)
{ {
auto p = new Gadget{n}; auto p = new Gadget{n};
// ... // ...
@@ -7268,7 +7283,7 @@ The following example is inefficient (because it has unnecessary allocation and
Instead, use a local variable: Instead, use a local variable:
void some_function(int n) void f(int n)
{ {
Gadget g{n}; Gadget g{n};
// ... // ...

View File

@@ -15,7 +15,8 @@ default: all
.PHONY: all .PHONY: all
all: \ all: \
check-markdown \ check-markdown \
check-references check-references \
check-notabs
$(BUILD_DIR): $(BUILD_DIR):
@@ -57,6 +58,14 @@ check-references: $(SOURCEPATH) $(BUILD_DIR) Makefile
## check if output has data ## check if output has data
if [ -s "build/CppCoreGuidelines.md.uniq" ]; then echo 'Found duplicate anchors:'; cat $(BUILD_DIR)/$(SOURCEFILE).uniq; false; fi if [ -s "build/CppCoreGuidelines.md.uniq" ]; then echo 'Found duplicate anchors:'; cat $(BUILD_DIR)/$(SOURCEFILE).uniq; false; fi
.PHONY: check-notabs
check-notabs: $(SOURCEPATH) $(BUILD_DIR) Makefile
# find lines with tabs
# old file still might be around
rm -f $(BUILD_DIR)/CppCoreGuidelines.md.tabs
# print file, add line numbers, remove tabs from nl tool, grep for remaining tabs, replace with stars
cat ../CppCoreGuidelines.md | nl -ba | sed -s 's/\(^[^\t]*\)\t/\1--/g' | grep -P '\t' | sed -s 's/\t/\*\*\*\*/g' > $(BUILD_DIR)/CppCoreGuidelines.md.tabs
if [ -s $(BUILD_DIR)/CppCoreGuidelines.md.tabs ]; then echo 'Warning: Tabs found:'; cat $(BUILD_DIR)/CppCoreGuidelines.md.tabs; false; fi;
#### install npm modules #### install npm modules
# install/update npm dependencies defined in file package.json # install/update npm dependencies defined in file package.json