1. General
1.1 Implementation Compliance
1.1.1 Ensure that code complies with the 2011 ISO C++ Language Standard
The current version of the C++ language is as defined by the ISO International Standard ISO/IEC 14882:2011(E) “Information technology — Programming languages — C++”.
Compilers often provide features beyond those defined in the Standard, and unrestricted sage of such features will likely hamper code portability. To this end, source code should be routinely parsed with a separate compiler or code analysis tool apart from the compiler used for production purposes.
#include <cstdint> void foo (int32_t i) { int32_t * a; __try // @@- Non-Compliant -@@ { a = new int32_t [i]; // ... } __finally // @@- Non-Compliant -@@ { delete [] a; } }
References
- HIC++ v3.3 – 1.3.1
- HIC++ v3.3 – 6.4
- HIC++ v3.3 – 13.3
- Meyers Notes – Reference Binding Rules
1.2 Redundancy
1.2.1 Ensure that all statements are reachable
For the purposes of this rule, missing else and default clauses are considered also. If a statement cannot be reached for any combination of function inputs (e.g. function arguments, global variables, volatile objects), it can be eliminated. For example, when the condition of an if statement is never false the else clause is unreachable. The entire if statement can be replaced with its ‘true’ sub-statement only. In practice two methods are used to detect unreachable code:
- Sparse conditional constant propagation
- Theorem proving
This is done by showing that non-execution of a statement is independent of function inputs. Since the values of variables are not used to determine unreachability, this restricted definition is decidable (see Section <verbatim> \ref{preamble.enforcement} </verbatim> ). A compiler may detect and silently remove unreachable statements as part of its optimizations. However, explicitly removing unreachable code has other benefits apart from efficiency: the structure of the function will be simplified. This will improve its maintainability and will increase the proportion of statements that can be reached through coverage analysis.
#include <cstdint> bool foo (int32_t a) { // ... return true; } void bar (int32_t b) { // @@- Non-Compliant: implicit else clause cannot be reached for any 'b' -@@ if (foo (b)) { // ... } foo (b); // @@+ Compliant +@@ // ... }
References
- HIC++ v3.3 – 5.3
- JSF AV C++ Rev C – 186
- MISRA C++:2008 – 0-1-1
1.2.2 Ensure that no expression or sub-expression is redundant
An expression statement with no side effects can be removed or replaced with a null statement without affecting behavior of the program. Similarly, it is sometimes possible to simplify an expression by removing operands that do not change the resulting value of the expression, for example a multiplication by 1 or 0. Redundant code causes unnecessary maintenance overhead and may be a symptom of a poor design.
#include <cstdint> void foo (int32_t & a) { a == 0; // @@- Non-Compliant: was this supposed to be an assignment -@@ }
References
HIC++ v3.3 – 10.10
1.3 Deprecated Features
1.3.1 Do not use the increment operator (++) on a variable of type bool
Incrementing an object with bool type results in its value been set to true. This feature was deprecated in the 1998 C++ Language Standard and thus may be withdrawn in a later version. Prefer to use an explicit assignment to true.
void foo (bool b) { ++b; // @@- Non-Compliant -@@ } void bar (bool b) { b = true; // @@+ Compliant: this is equivalent +@@ }
References
- HIC++ v3.3 – 10.16
- C++98 – 5.3.2/1
1.3.2 Do not use the register keyword
Most compilers ignore the register keyword, and perform their own register assignments. Moreover, this feature was deprecated in the 2011 C++ language standard and thus may be withdrawn in a later version.
#include <cstdint> int32_t square (register int32_t a) // @@- Non-Compliant -@@ { return a * a; }
References
- HIC++ v3.3 – 8.3.3
- C++11 – D.2
1.3.3 Do not use the C Standard Library .h headers
The C standard library headers are included in C++ for compatibility. However, their inclusion was deprecated in the 1998 C++ language standard and thus they may be withdrawn in a later version. Instead of <name.h> prefer to use <cname>.
#include <cstdint> #include <string.h> // @@- Non-Compliant -@@ #include <cstring> // @@+ Compliant +@@ int32_t foo (const char * s) { return 2 * std::strlen (s); }
References
- HIC++ v3.3 – 17.1
- C++98 – 17.4.1.2/7
1.3.4 Do not use deprecated STL library features
The following STL features were deprecated in the 2011 C++ language standard and thus they may be withdrawn in a later version.
- std::auto_ptr
- std::bind1st
- std::bind2nd
- std::ptr_mem_fun
- std::ptr_mem_fun_ref
- std::unary_function
- std::binary_function
Of particular note is std::auto_ptr as it has been suggested that a search and replace of this type to std::unique_ptr, may uncover latent bugs due to the incorrect use of std::auto_ptr.
#include <cstdint> #include <memory> void foo () { std::auto_ptr<int32_t> p1 (new int32_t(0)); // @@- Non-Compliant -@@ std::unique_ptr<int32_t> p2 (new int32_t(0)); // @@+ Compliant +@@ }
References
- HIC++ v3.3 – 17.21
- Sutter Guru of the Week (GOTW) – 89
- C++11 – D