| 是否进行空指针校验 | whether to verify the pointer is null/nullptr |
| 是否进行返回值校验 | whether to verify the function's return value |
| 是否正确释放new/malloc内存 | whether new/malloc memory is released correctly |
| 是否修改热点函数/算法/算子 | whether to modify hotspot function / algorithm / operation |
| 是否考虑并发场景 | whether to consider concurrent scenarios |
| 是否考虑通信场景 | whether to consider communication scenario |
| 是否符合编码规范 【编码规范】 | Whether to comply with coding specifications [coding specification reference] |
| 是否遵守SOLID原则/迪米特法则 | Whether to comply with SOLID principle / Demeter's law |
| 是否涉及模块/特性间交互【若涉及请概述实现思路】 | Whether the interaction between modules / features is involved (if yes, please outline the implementation ideas) |
| 是否具备UT测试用例看护 && 测试用例为有效用例【若无测试用例请说明原因】 | Whether there is UT test case && the test case is a valid (if there is no test case, please explain the reason) |
| 秘钥是否被正确加载、释放 | whether the secret key is loaded/released correctly |
| 是否充分考虑接口的异常场景 | whether the interface exception scenarios are fully considered |
| 是否正确记录错误信息 | whether the error is recorded appropriately |
@@ -51,7 +51,7 @@ C++ files are named in the format of lowercase letters + underscores (_). The fi
> a_b_c.cc
> a_b_c_test.cc
##### Rule 1.1.2 Use lowercase letters and underscores (_) to name local variables and parameters.
##### Rule 1.1.2 Use lowercase letters and underscores (_) to name local variables and parameters
```cpp
void FooBar(int func_param) {
@@ -59,7 +59,7 @@ void FooBar(int func_param) {
}
```
##### Rule 1.1.3 Use lowercase letters and underscores (_) to name member variables, with an underscore (_) as the suffix.
##### Rule 1.1.3 Use lowercase letters and underscores (_) to name member variables, with an underscore (_) as the suffix
```cpp
class FooBar {
@@ -68,7 +68,7 @@ class FooBar {
};
```
##### Rule 1.1.4 Use uppercase letters and underscores (_) in macro names.
##### Rule 1.1.4 Use uppercase letters and underscores (_) in macro names
```cpp
#define MS_LOG(...)
@@ -86,22 +86,42 @@ enum UrlTableErrors {
};
```
##### Rule 1.1.6 Naming of function
1. Class member variable accessor:naming of accessor should comply with naming rule of variables and parameters, such as:
```c++
int count() {return this->count_;}
```
2. Class member variable modifier:naming of modifier should be started with `set_` and followed by variables or parameters name, such as:
```c++
void set_count(int count) {this->count_ = count;}
```
3. Other class member functions/common functions: named based on the large hump rules, such as:
```c++
void FindPattern(...);
```
#### <a name="fmt">1.2 Format</a>
##### Recommendation 1.2.1 Each line contains a maximum of 120 characters.
##### Recommendation 1.2.1 Each line contains a maximum of 120 characters
If a line contains more than 120 characters, start a new line properly.
##### Rule 1.2.2 Use spaces to indent, two at a time.
##### Rule 1.2.2 Use spaces to indent, two at a time
##### Rule 1.2.3 When declaring a pointer or referencing variables or parameters, follow variable names with `&` and `*` and place a space on the other side.
##### Rule 1.2.3 When declaring a pointer or referencing variables or parameters, follow variable names with `&` and `*` and place a space on the other side
```cpp
char *c;
const std::string &str;
```
##### Rule 1.2.4 Use braces to include an if statement.
##### Rule 1.2.4 Use braces to include an if statement
```cpp
// Even if the if branch code is within one line, braces are required.
@@ -110,9 +130,9 @@ if (cond) {
}
```
##### Rule 1.2.5 Use braces for loop statements such as for and while statements, even if the loop body is empty or there is only one loop statement.
##### Rule 1.2.5 Use braces for loop statements such as for and while statements, even if the loop body is empty or there is only one loop statement
##### Rule 1.2.6 Keep a consistent line break style for expressions and ensure that operators are placed at the end of a line.
##### Rule 1.2.6 Keep a consistent line break style for expressions and ensure that operators are placed at the end of a line
```cpp
int a = a_very_long_expression +
@@ -120,7 +140,7 @@ int a = a_very_long_expression +
a_very_very_very_long_expression;
```
##### Rule 1.2.7 Each variable definition or assignment statement occupies one line.
##### Rule 1.2.7 Each variable definition or assignment statement occupies one line
All .h and .cc files must contain the following copyright statements:
```cpp
```cpp
/**
* Copyright 2019 Huawei Technologies Co., Ltd
*
@@ -150,14 +170,13 @@ All .h and .cc files must contain the following copyright statements:
* See the License for the specific language governing permissions and
* limitations under the License.
*/
```
> Notes:
> Files created in 2020 should contain `Copyright 2020 Huawei Technologies Co., Ltd`.
> Files created in 2019 and modified in 2020 should contain `Copyright 2019-2020 Huawei Technologies Co., Ltd`.
##### Rule 1.3.2 A comment is placed above or to the right of the code. There must be a space between the comment character and the comment content, and at least one space between the code and its comment on the right. Use `//`, not `/**/`.
##### Rule 1.3.2 A comment is placed above or to the right of the code. There must be a space between the comment character and the comment content, and at least one space between the code and its comment on the right. Use `//`, not `/**/`
```cpp
// this is multi-
@@ -165,34 +184,33 @@ All .h and .cc files must contain the following copyright statements:
int foo; // this single-line comment
```
##### Rule 1.3.3 Do not use comments such as TODO, TBD, and FIXME in code. You are advised to submit an issue for tracking.
##### Rule 1.3.3 Do not use comments such as TODO, TBD, and FIXME in code. You are advised to submit an issue for tracking
##### Recommendation 1.3.4 Function header comments with no content are forbidden.
##### Recommendation 1.3.4 Function header comments with no content are forbidden
Not all functions require header comments. You are advised to use the name of the function as its comment and write header comments if there is the need. For the information that cannot be expressed by the function prototype but is expected to be known by readers, function header comments are required.
Do not write useless or redundant function headers. The function header comments are optional, including but not limited to function description, return values, performance constraints, usage, memory conventions, algorithm implementation, and reentrant requirements.
### <a name="cc">2. General Coding</a>
#### <a name="cdes">2.1 Code Design</a>
##### Rule 2.1.1 Check the validity of all external data, including but not limited to function input parameters, external input named lines, files, environment variables, and user data.
##### Rule 2.1.1 Check the validity of all external data, including but not limited to function input parameters, external input named lines, files, environment variables, and user data
##### Rule 2.1.2 When transferring function execution results, preferentially use return values and avoid output parameters.
##### Rule 2.1.2 When transferring function execution results, preferentially use return values and avoid output parameters
```cpp
FooBar *Func(const std::string &in);
```
##### Rule 2.1.3 Delete invalid, redundant, or never-executed code.
##### Rule 2.1.3 Delete invalid, redundant, or never-executed code
Although most modern compilers in many cases can alert you to invalid or never executed code, responding alarms should be identified and cleared.
Identify and delete invalid statements or expressions from the code.
##### Rule 2.1.4 Follow additional specifications to the C++ exception mechanism.
##### Rule 2.1.4 Follow additional specifications to the C++ exception mechanism
###### Rule 2.1.4.1 Specify the types of exceptions to be captured. Do not capture all exceptions.
###### Rule 2.1.4.1 Specify the types of exceptions to be captured. Do not capture all exceptions
```cpp
// Incorrect
@@ -211,7 +229,7 @@ try {
#### <a name="inc">2.2 Header File and Preprocessing</a>
##### Rule 2.2.1 Use the new standard C++ header file.
##### Rule 2.2.1 Use the new standard C++ header file
```cpp
// Correct
@@ -220,25 +238,24 @@ try {
#include <stdlib.h>
```
##### Rule 2.2.2 Header file cyclic dependency is forbidden.
##### Rule 2.2.2 Header file cyclic dependency is forbidden
An example of cyclic dependency (also known as circular dependency) is: a.h contains b.h, b.h contains c.h, and c.h contains a.h. If any of these header files is modified, all code containing a.h, b.h, and c.h needs to be recompiled.
The cyclic dependency of header files reflects an obviously unreasonable architecture design, which can be avoided through optimization.
##### Rule 2.2.3 Do not include unnecessary header files.
##### Rule 2.2.4 It is prohibited to reference external function interfaces and variables in extern declaration mode.
##### Rule 2.2.3 Do not include unnecessary header files
##### Rule 2.2.5 Do not include header files in extern "C".
##### Rule 2.2.4 It is prohibited to reference external function interfaces and variables in extern declaration mode
##### Rule 2.2.6 Do not use "using" to import namespace in a header file or before #include statements.
##### Rule 2.2.5 Do not include header files in extern "C"
##### Rule 2.2.6 Do not use "using" to import namespace in a header file or before #include statements
#### <a name="dtype">2.3 Data Type</a>
##### Recommendation 2.3.1 Do not abuse typedef or #define to alias basic types.
##### Recommendation 2.3.1 Do not abuse typedef or #define to alias basic types
##### Rule 2.3.2 Use “using” instead of typedef to define the alias of a type to avoid shot-bomb modification caused by type changes.
##### Rule 2.3.2 Use “using” instead of typedef to define the alias of a type to avoid shot-bomb modification caused by type changes
##### Rule 2.4.1 Do not use macros to replace constants.
##### Rule 2.4.1 Do not use macros to replace constants
##### Rule 2.4.2 Do not use magic numbers or character strings.
##### Rule 2.4.2 Do not use magic numbers or character strings
##### Recommendation 2.4.3 Ensure that a constant has only one responsibility.
##### Recommendation 2.4.3 Ensure that a constant has only one responsibility
#### <a name="var">2.5 Variable</a>
##### Recommendation 2.5.1 Use namespaces to manage global constants. If the global constants are closely tied to a class, you can use static member constants to manage them.
##### Recommendation 2.5.1 Use namespaces to manage global constants. If the global constants are closely tied to a class, you can use static member constants to manage them
```cpp
namespace foo {
@@ -270,17 +287,17 @@ namespace foo {
}
```
##### Rule 2.5.2 Do not use global variables. Use the singleton pattern cautiously to avoid abuse.
##### Rule 2.5.2 Do not use global variables. Use the singleton pattern cautiously to avoid abuse
##### Rule 2.5.3 A variable cannot be referenced again if it is contained in an increment or decrement operation in an expression.
##### Rule 2.5.3 A variable cannot be referenced again if it is contained in an increment or decrement operation in an expression
##### Rule 2.5.4 After the resource is released, immediately assign a new value to the pointer variable that points to a resource handle or descriptor, or set the value to NULL.
##### Rule 2.5.4 After the resource is released, immediately assign a new value to the pointer variable that points to a resource handle or descriptor, or set the value to NULL
##### Rule 2.5.5 Do not use uninitialized variables.
##### Rule 2.5.5 Do not use uninitialized variables
#### <a name="exp">2.6 Expression</a>
##### Recommendation 2.6.1 When comparing expressions, follow the principle that the left side tends to change and the right side tends to remain unchanged.
##### Recommendation 2.6.1 When comparing expressions, follow the principle that the left side tends to change and the right side tends to remain unchanged
```cpp
// Correct
@@ -294,7 +311,7 @@ if (SUCCESS != ret) {
}
```
##### Rule 2.6.2 Use parentheses to specify the operator precedence to avoid rookie errors.
##### Rule 2.6.2 Use parentheses to specify the operator precedence to avoid rookie errors
##### Rule 2.10.4 Use a smart pointer to manage objects. Do not use new or delete.
##### Rule 2.10.4 Use a smart pointer to manage objects. Do not use new or delete
##### Rule 2.10.5 Do not use auto_ptr.
##### Rule 2.10.5 Do not use auto_ptr
##### Rule 2.10.6 For formal parameters of pointer and reference types, if the parameters do not need to be modified, use const.
##### Rule 2.10.6 For formal parameters of pointer and reference types, if the parameters do not need to be modified, use const
##### Rule 2.10.7 Use the array length as a function parameter when the array is a function parameter.
##### Rule 2.10.7 Use the array length as a function parameter when the array is a function parameter
```cpp
int ParseMsg(BYTE *msg, size_t msgLen) {
@@ -357,17 +371,17 @@ int ParseMsg(BYTE *msg, size_t msgLen) {
}
```
#### <a name="str">2.11 String</a>
#### <a name="str">2.11 String</a>
##### Rule 2.11.1 When saving a string, ensure that it has '\0' at the end.
##### Rule 2.11.1 When saving a string, ensure that it has '\0' at the end
#### <a name="ast">2.12 Assert</a>
##### Rule 2.12.1 Assert cannot be used to verify errors that may occur when the program is running. To handle possible running errors, use error processing code.
##### Rule 2.12.1 Assert cannot be used to verify errors that may occur when the program is running. To handle possible running errors, use error processing code
#### <a name="cls">2.13 Class and Object</a>
##### Rule 2.13.1 When a single object is released, delete is used. When an array object is released, delete [] is used.
##### Rule 2.13.1 When a single object is released, delete is used. When an array object is released, delete [] is used
```cpp
const int kSize = 5;
@@ -379,9 +393,10 @@ number_array = nullptr;
delete number;
number = nullptr;
```
##### Rule 2.13.2 Do not use std::move to operate the const object.
##### Rule 2.13.3 Strictly use virtual/override/final to modify virtual functions.
##### Rule 2.13.2 Do not use std::move to operate the const object
##### Rule 2.13.3 Strictly use virtual/override/final to modify virtual functions
```cpp
class Base {
@@ -402,7 +417,7 @@ class FinalDerived : public Derived {
#### <a name="fdes">2.14 Function Design</a>
##### Rule 2.14.1 Use the RAII feature to help track dynamic allocation.
##### Rule 2.14.1 Use the RAII feature to help track dynamic allocation
```cpp
// Correct
@@ -412,7 +427,7 @@ class FinalDerived : public Derived {
}
```
##### Rule 2.14.2 Avoid capturing by reference in lambdas that will not be used locally.
##### Rule 2.14.2 Avoid capturing by reference in lambdas that will not be used locally
```cpp
{
@@ -422,25 +437,25 @@ class FinalDerived : public Derived {
}
```
##### Rule 2.14.3 Do not use default parameter values for virtual functions.
##### Rule 2.14.3 Do not use default parameter values for virtual functions
##### Recommendation 2.14.4 Use strongly typed parameters or member variables. Do not use void*.
##### Recommendation 2.14.4 Use strongly typed parameters or member variables. Do not use void*
#### <a name="fuse">2.15 Function Usage</a>
##### Rule 2.15.1 The input parameter must be transferred before the output parameter.
##### Rule 2.15.1 The input parameter must be transferred before the output parameter
##### Rule 2.15.3 In the scenario where ownership is not involved, use T * or const T & instead of the smart pointer as the transfer parameter.
##### Rule 2.15.3 In the scenario where ownership is not involved, use T * or const T & instead of the smart pointer as the transfer parameter
```cpp
// Correct
@@ -449,7 +464,7 @@ class FinalDerived : public Derived {
bool Func(std::shared_ptr<FooBar> in);
```
##### Rule 2.15.4 To transfer the ownership, you are advised to use shared_ptr + move to transfer parameters.
##### Rule 2.15.4 To transfer the ownership, you are advised to use shared_ptr + move to transfer parameters
```cpp
class Foo {
@@ -460,7 +475,7 @@ class Foo {
};
```
##### Rule 2.15.5 Use explicit to modify single-parameter constructors and do not use explicit to modify multi-parameter constructors.
##### Rule 2.15.5 Use explicit to modify single-parameter constructors and do not use explicit to modify multi-parameter constructors
```cpp
explicit Foo(int x); //good :white_check_mark:
@@ -469,7 +484,7 @@ class Foo {
explicit Foo(int x, int y); //bad :x:
```
##### Rule 2.15.6 Copy constructors and copy assignment operators should be implemented or hidden together.
##### Rule 2.15.6 Copy constructors and copy assignment operators should be implemented or hidden together
```cpp
class Foo {
@@ -481,11 +496,11 @@ class Foo {
};
```
##### Rule 2.15.7 [Question] Do not save or delete pointer parameters.
##### Rule 2.15.7 [Question] Do not save or delete pointer parameters
##### Rule 2.15.8 [Question] Do not use insecure functions as listed.
##### Rule 2.15.8 [Question] Do not use insecure functions as listed
##### Rule 2.15.9 [Question] Do not use insecure exit functions as listed.
##### Rule 2.15.9 [Question] Do not use insecure exit functions as listed
```cpp
{
@@ -499,16 +514,16 @@ class Foo {
}
```
##### Rule 2.15.10 Do not use the rand function to generate pseudo-random numbers for security purposes.
##### Rule 2.15.10 Do not use the rand function to generate pseudo-random numbers for security purposes
The rand() function in the C standard library generates pseudo-random numbers. To generate random numbers, use /dev/random.
##### Rule 2.15.11 Do not use the string class to store sensitive information.
##### Rule 2.15.11 Do not use the string class to store sensitive information
The string class is a character string management class defined in C++. If sensitive information such as passwords is operated through the string class, the sensitive information can be
scattered in various places of the memory and cannot be cleared.
In the following code, the Foo function obtains the password, saves it to the string variable password, and then transfers it to the VerifyPassword function. In this process,
In the following code, the Foo function obtains the password, saves it to the string variable password, and then transfers it to the VerifyPassword function. In this process,
two copies of the password exist in the memory.
```cpp
@@ -521,6 +536,7 @@ int Foo() {
...
}
```
Sensitive information must be stored using char or unsigned char. For example:
```cpp
@@ -535,31 +551,31 @@ int Foo() {
}
```
##### Rule 2.15.12 Clear sensitive information in the memory immediately after use.
##### Rule 2.15.12 Clear sensitive information in the memory immediately after use
Sensitive information, such as passwords and keys, must be cleared immediately after being used to prevent attackers from obtaining the information.
#### <a name="mem">2.16 Memory</a>
##### Rule 2.16.1 Check whether memory allocation is successful.
##### Rule 2.16.1 Check whether memory allocation is successful
If the memory allocation fails, the subsequent operations may have undefined behavior risks. For example, if malloc fails to be applied for and a null pointer is returned, dereference of the null pointer is an undefined behavior.
##### Rule 2.16.2 Do not reference uninitialized memory.
##### Rule 2.16.2 Do not reference uninitialized memory
The memory allocated by malloc and new is not initialized to 0. Ensure that the memory is initialized before being referenced.
##### Rule 2.16.3 Do not use the realloc() function.
##### Rule 2.16.3 Do not use the realloc() function
The behavior of the realloc function varies with parameters. This is not a well-designed function. Although it provides some convenience in coding, it can easily cause various bugs.
##### Rule 2.16.4 Do not use the alloca() function to apply for stack memory.
##### Rule 2.16.4 Do not use the alloca() function to apply for stack memory
Neither POSIX nor C99 defines the alloca() behavior. Some platforms do not support this function. Using alloca() reduces program compatibility and portability. This function requests memory in the stack frame. The requested size may exceed the stack boundary, affecting code execution.
#### <a name="file">2.17 File</a>
##### Rule 2.17.1 File paths must be canonicalized before use.
##### Rule 2.17.1 File paths must be canonicalized before use
A file path that comes from external data must be canonicalized first. If the file path is not canonicalized, attackers can construct a malicious file path to access the file without authorization.
For example, an attacker can construct “../../../etc/passwd” to access any file.
char *text = ReadFileContent(untrustPath); // Bad: Did not check whether the untrustPath can be accessed before the data is read.
```
[Compliant Code Example]
Canonicalize the file path and then check whether the path is valid in the program.
```cpp
char *fileName = GetMsgFromRemote();
...
@@ -590,11 +608,11 @@ if (!IsValidPath(path)) { // Good: Check whether the file location is correct
}
char *text = ReadFileContent(untrustPath);
```
Exceptions:
Command line programs that run on the console, or file paths that are manually entered on the console are exempted from this rule.
##### Rule 2.17.2 Do not create temporary files in the shared directory.
##### Rule 2.17.2 Do not create temporary files in the shared directory
Temporary files of a program must be exclusively used by itself. Otherwise, other users of the shared directory may obtain additional information about the program, resulting in information leakage. Therefore, do not create temporary files that should be used only by the program itself in any shared directory.
For example, the /tmp directory in Linux is a shared directory that all users can access. Do not create temporary files that should be used only by the program itself in this directory.
@@ -625,7 +643,7 @@ For example, the /tmp directory in Linux is a shared directory that all users ca
</tr>
</table>
##### Rule 2.15.18 Use secure functions provided by the community in the secure function library. Do not use dangerous functions related to memory operations.
##### Rule 2.15.18 Use secure functions provided by the community in the secure function library. Do not use dangerous functions related to memory operations
<table>
<thead>
@@ -772,12 +790,11 @@ For example, the /tmp directory in Linux is a shared directory that all users ca
</tr>
</table>
##### Rule 2.18.2 Correctly set the destMax parameter in secure functions
##### Rule 2.18.2 Correctly set the destMax parameter in secure functions.
##### Rule 2.18.3 Do not encapsulate secure functions
##### Rule 2.18.3 Do not encapsulate secure functions.
##### Rule 2.18.4 Do not rename secure functions using macros.
##### Rule 2.18.4 Do not rename secure functions using macros
```cpp
#define XXX_memcpy_s memcpy_s
@@ -785,10 +802,10 @@ For example, the /tmp directory in Linux is a shared directory that all users ca
##### Rule 2.18.5 Do not customize secure functions.
##### Rule 2.18.5 Do not customize secure functions
Using macros to rename secure functions does not help static code scanning tools (non-compiled) customize rules for the misuse of secure functions. In addition, there are various naming styles.
In addition, it is not conducive to reminding the code developer of the real usage of functions, and may easily cause misunderstanding of the code and misuse of the renamed secure functions. Renaming secure functions will not
In addition, it is not conducive to reminding the code developer of the real usage of functions, and may easily cause misunderstanding of the code and misuse of the renamed secure functions. Renaming secure functions will not
affect the checking capability of the secure functions.
```cpp
@@ -797,9 +814,9 @@ void MemcpySafe(void *dest, unsigned int destMax, const void *src, unsigned int
}
```
##### Rule 2.18.6 Check the return values of secure functions and correctly process them.
##### Rule 2.18.6 Check the return values of secure functions and correctly process them
In principle, if a secure function is used, its return value must be checked. If the return value is ! = EOK, this function should be returned immediately,
In principle, if a secure function is used, its return value must be checked. If the return value is ! = EOK, this function should be returned immediately,
and cannot be continued.
A secure function may have multiple erroneous return values. If a secure function returns a failure, perform the following operations (one or more) based on specific product scenario before it is returned
:
@@ -819,14 +836,15 @@ A secure function may have multiple erroneous return values. If a secure functio
}
```
##### Rule 2.18.7 Do not use external controllable data as function parameters for starting processes, such as system, popen, WinExec, ShellExecute, execl, xeclp, execle, execv, execvp and CreateProcess.
##### Rule 2.18.7 Do not use external controllable data as function parameters for starting processes, such as system, popen, WinExec, ShellExecute, execl, xeclp, execle, execv, execvp and CreateProcess
##### Rule 2.18.8 Do not use external controllable data as parameters for module loading functions such as dlopen/LoadLibrary.
##### Rule 2.18.8 Do not use external controllable data as parameters for module loading functions such as dlopen/LoadLibrary
##### Rule 2.18.9 Do not call non-asynchronous secure functions in signal processing routines.
##### Rule 2.18.9 Do not call non-asynchronous secure functions in signal processing routines
Signal processing routines should be as simple as possible. If a non-asynchronous secure function is called in a signal processing routine, the execution of the function may not generate expected results.
The signal handler in the following code writes logs by calling fprintf(), but the function is not asynchronous secure function.
本规范以[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)为基础,参考华为通用编码规范、安全编程规范,并结合业界共识整理而成,参与MindSpore社区的开发者首先需要遵循本规范内容,其余遵循Google C++ Style Guide规范;