From bece9883e1b0c29840d4dfac80dfc3d8478fe2c7 Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:14:23 +0100 Subject: [PATCH 1/7] Changed "Never use 'using' In a Header File" guideline. Changed it to "Never use 'using namespace' ...". Also added some more explanation. --- 03-Style.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/03-Style.md b/03-Style.md index 43e45c5..0ee0f28 100644 --- a/03-Style.md +++ b/03-Style.md @@ -90,9 +90,11 @@ int myFunc() which would be impossible if the function comment header used `/* */` -## Never Use `using` In a Header File +## Never Use `using namespace` In a Header File This causes the name space you are `using` to be pulled into the namespace of the header file. +It litters the own namespace and it may lead to name collisions in the future. +Writing `using namespace` in an implementation file is fine though. ## Include Guards From 2e55a671e1ad3bee07f847d93b8a929dd0e7eb7e Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:17:48 +0100 Subject: [PATCH 2/7] Added "#pragma once" idea to include guards guideline. --- 03-Style.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/03-Style.md b/03-Style.md index 0ee0f28..7ba3449 100644 --- a/03-Style.md +++ b/03-Style.md @@ -113,6 +113,9 @@ class MyClass { #endif ``` +You may also consider to use the `#pragma once` directive instead which is quasi standard across many compilers. +It's short and makes the intent clear. + ## {} are required for blocks. Leaving them off can lead to semantic errors in the code. From e01358c20b5561fc92dcdae542e964538dc1758b Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:26:03 +0100 Subject: [PATCH 3/7] Inserted reasonable line length and gave reasons. Gave some reasons behind the guideline to use a reasonable line length. --- 03-Style.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/03-Style.md b/03-Style.md index 7ba3449..72ab4b1 100644 --- a/03-Style.md +++ b/03-Style.md @@ -160,6 +160,10 @@ if (x && y && myFunctionThatReturnsBool() } ``` +Many projects and coding standards have a soft guideline that one should try to use less than about 80 or 100 characters per line. +Such code is generally easier to read. +It also makes it possible to have two separate file next to each other on one screen without having a tiny font. + ## Use "" For Including Local Files ... `<>` is [reserved for system includes](http://blog2.emptycrate.com/content/when-use-include-verses-include). From 285da913f639c68ca1d6991c72880d711ce2299a Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:28:20 +0100 Subject: [PATCH 4/7] Fixed typo: "memeber" -> "member" --- 03-Style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-Style.md b/03-Style.md index 72ab4b1..aea2d19 100644 --- a/03-Style.md +++ b/03-Style.md @@ -207,7 +207,7 @@ private: // Good Idea -// C++'s memeber initializer list is unique to the language and leads to +// C++'s member initializer list is unique to the language and leads to // cleaner code and potential performance gains that other languages cannot // match class MyClass From 2a7773fcbb379b2d0fa6b429338a91362dea118b Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:32:33 +0100 Subject: [PATCH 5/7] Improved explanation for "Avoid Compiler Macros". --- 03-Style.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/03-Style.md b/03-Style.md index aea2d19..92a038e 100644 --- a/03-Style.md +++ b/03-Style.md @@ -233,16 +233,19 @@ There is almost never a reason to declare an identifier in the global namespaces Compiler definitions and macros are replaced by the pre-processor before the compiler is ever run. This can make debugging very difficult because the debugger doesn't know where the source came from. ```cpp +// Bad Idea +#define PI 3.14159; + // Good Idea namespace my_project { class Constants { public: + // if the above macro would be expanded, then the following line would be: + // static const double 3.14159 = 3.14159; + // which leads to an compile-time error. Sometimes such errors are hard to understand. static const double PI = 3.14159; } } - -// Bad Idea -#define PI 3.14159; ``` From 0a159446650b76ad229ad216d286f67f3dca4242 Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:39:47 +0100 Subject: [PATCH 6/7] Added C++11 guideline for member initialization. --- 03-Style.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/03-Style.md b/03-Style.md index 92a038e..2f5a03e 100644 --- a/03-Style.md +++ b/03-Style.md @@ -223,6 +223,16 @@ private: }; ``` +In C++11 you may consider to always give each member a default value, e.g. by writing +```cpp +// ... // +private: + int m_value = 0; +// ... // +``` +inside the class body. This makes sure that no constructor ever "forgets" to initialize a member object. +Forgetting to initialize a member is a source of undefined behaviour bugs which are often extremely hard to find. + ## Always Use Namespaces From a49760dde683c9751af19c8f8aa0c2569bab6024 Mon Sep 17 00:00:00 2001 From: Ralph Tandetzky Date: Sat, 7 Mar 2015 20:46:00 +0100 Subject: [PATCH 7/7] Gave explanation for 'assert' and use of templates. --- 03-Style.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/03-Style.md b/03-Style.md index 2f5a03e..ab60aaa 100644 --- a/03-Style.md +++ b/03-Style.md @@ -282,9 +282,11 @@ assert(registerSomeThing()); // make sure that registerSomeThing() returns true ``` The above code succeeds when making a debug build, but gets removed by the compiler when making a release build, giving you different behavior between debug and release builds. +This is because `assert()` is a macro which expands to nothing in release mode. ## Don't be afraid of templates They can help you stick to DRY principles. +They should be preferred to macros, because macros do not honor namespaces, etc. ## Use operator overloads judiciously