编码风格对于软件开发者而言十分重要,对大型的开发团队更是如此,每个公司也都有自己的风格规定。在这里分享一套我在 C/C++项目中使用的 coding style。这套编码风格参考整理了 Google C++ coding style,RDK coding guidelines,NASA coding style,和一些开源的编码风格(见附录)。
规范编码风格的目的不是形式化,而是为了提高写代码效率和代码的一致性,同事提高代码的可读性与可维护性。比如注释部分我花了很大的篇幅介绍Doxygen工具的注释风格,并且对每一个public API都要求有清晰、详细的注释。
将整理好的风格整理成Astyle的配置,写一个batch脚本或者在git hook中添加Astyle,即可使用batch文件或者git commit后自动修改代码格式。
1 Project Structure
1.1 File Guards
All header files should use #define to avoid multi-declaration. Naming format should be __H_For example, the file adsp/dirver/include/adsp_driver_adc.h in platform adsp should have the following guard.:
#ifndef ADSP_DRIVER_ADC_H_#define ADSP_DRIVER_ADC_H_...#endif /* ADSP_DRIVER_ADC_H_ */
1.1 Order of Includes
Include headers in the following order: Related header, C system headers, C++ standard library headers, other libraries’ headers, your project’s headers.For example, In adsp/dirver/src/adsp_driver_adc.c, whose main purpose is to implement or test the stuff in adsp/dirver/include/adsp_driver_adc.h, order your includes as follows:
- self.h.
- A blank line
- C/C++ system headers (more precisely: headers in angle brackets with the .h extension), e.g. , .
- A blank line
- Other libraries’ .h files.
- Your project’s .h files.
1.2 File Names
File names should include both platform name and module functions. For example:
- A driver file name example is mcu_driver_adc.c.
- A utility file name example is utility_crc32.c.
- A HAL file name example is hal_adc.c, hal_adc.h.
- A app file name example is app_gateway.c.
- A board file name example of project XXX isxxx_audio.c.
2. Code Format
2.1 Brace Placement
Allman style is used for brace placement, e.g.
while (x == y) { something(); somethingelse(); }
2.2 Indentations
Use 4 spaces rather than tabs as printers as users might have different tab settings.Use single line spacing between logical blocks of code.Use double line spacing between functions.Linux(LF) end line style is used.
2.3 Code Length
Code in single line should not exceed 80 characters. When breaking lines, use the natural logical breaks to determine where the newline goes. Indent the continuation line to illustrate its logical relationship to the rest of the code in the line.
if (thisVariable1 == thatVariable1 || thisVariable2 == thatVariable2 || thisVariable3 == thatVariable3) bar();
becomes:
if (thisVariable1 == thatVariable1 || thisVariable2 == thatVariable2 || thisVariable3 == thatVariable3) bar();
2.4 Brackets
Use a pure-block, fully bracketed style for blocks of code. This means put brackets around all conditional code blocks, even one-line blocks.
if(statement == true){ foo_true();}else{ foo_false();}
2.5 Spaces
- Insert space padding around operators. E.g.,
if (foo == 2) a = bar((b - c) * a, d--);
3. Naming Conventions
- All identifiers (variables, constants, Classes etc. ) declared should have meaningful names.
- Have naming conventions to differentiate between local and global data.
- Identifiers may have their types attached to their names for clarity and consistency.
- In case where the language has support for header file, ensure all user defined header file should have the same name as the source file that is referenced in.
- Names should be readable and self documenting. Abbreviations and contractions are to be discouraged. Abbreviations are allowed when they follow common usage within the domain.
- Identifiers should not exceed 31 characters.
3.1 Files
File names should be named with lower case and underscores.
adsp_driver_adc.c adsp_driver_adc.h
3.2 Macros
Macro names should be named with all capitals and underscores.
#define ROUND(x) ...#define PI_ROUNDED 3.0
3.3 Variables
Data Type | Prefix/postfix | Sample Variable Names |
---|---|---|
general variable | lowerCamelCase | sequenceNo |
const | k | const int32_t kSequenceNo |
static | s | static int32_t sSequenceNo |
enumerated data type | e | eCapabilityMode |
array | a | int32_t aSequenceNo[10] |
pointer | p | int32_t *pSequenceNo |
global | g | gAudioStruct |
struct | PascalCase_s | AudioStruct_s |
typedef | PascalCase_t | typedef struct AudioInfo_st {} AudioInfo_t; |
member variable (C++) | m | mClassMember |
class (C++) | Pascal Case | class AudioObject |
template (C++) | T | template class TAudioTemp |
namespace (C++) | N | namespace NAudioName … |
- Use (uint8_t, int32_t etc).
- Use the smallest required scope.
- Variables in a file (outside functions) are always static.
- Avoid to use global variables (use functions to set/get static variables).
- # &,* is aligned to names, e.g., uint32_t *pAddress
3.4 Functions
Global function names start with lower case module name + underscore + camel case function name. E.g., one function in doxygen.c is
uint32_t doxygen_theFirstFunction(uint32_t param1, uint32_t param2);
one function in adsp_driver_adc.c is
void adsp_driver_adc_readValue(uint8_t channel);
Local static function names apply lowerCamelCase rule, e.g., one function in adsp_driver_adc.c is
// file adsp_driver_adc.cstatic void getInstance(void)
Functions in C++ class should always apply PascalCase rule, e.g. ,
class AudioObject{ uint8_t *GetObjectName(void);}
4. Comments
Comments are used for the benefits of code readers as well as developers. So it is recommended that all comments should be written with simple and straightforward words, and English words only.
Doxygen is applied to generate documents according to code comments. Therefore, the rules of Doxygen should be strictly followed.
For better document graphic illustration, Grapghviz is recommended to be installed and used in Doxygen. Both Doxygen and Grapghviz can be installed in Cygwin.
Download link:
Grapghviz
https://graphviz.gitlab.io/_pages/Download/windows/graphviz-2.38.msigraphviz.gitlab.io
Doxygen
http://doxygen.nl/files/doxygen-1.8.18-setup.exedoxygen.nl
4.1 File Banners
Every header file should have a function banner as follows :
/***************************************************************************** * Portfolio Info ****************************************************************************/ /** * @file header.h * @brief Brief file introduction. * * Detailed file introduction. * * @author Name * @date day month year * @see Related link. *//** * @addtogroup API name * @brief Brief API description. * * Detailed api description. * * @{ */#ifndef _HEADER_NAME_H#define _HEADER_NAME_H#ifdef __cplusplusextern "C" {#endif/* INCLUDE FILES *//* GLOBAL DEFINES *//* GLOBAL VARIABLES *//* GLOBAL FUNCTIONS */ ...#ifdef __cplusplus}#endif#endif /* _HEADER_NAME_H *//** @}*/
Every source file should have a function banner as follows :
/***************************************************************************** * Portfolio Info ****************************************************************************/ /** * @file file.c * @brief Brief introduction. * * Here typically goes a more extensive explanation of what the source contains. * * @author Name * @date day month year * @see Related link. *//* INCLUDE FILES *//* MODULE CONSTANTS *//* MODULE VARIABLES *//* MODULE PROTOTYPES *//* MODULE FUNCTIONS */
4.2 Function Banners
Detailed function banners should be used in header files since the corresponding c file(s) are not necessarily made available to the user, nor should the user need to read the c file in order to understand how the functions there should be used. Everything should be made obvious from the header file alone.
For static functions in c file(s), function banners are required to use for developing maintenance.
Every function should have a function banner as follows:
/** * @brief Brief introduction. * * Detailed introduction. * * @param [in] param1 Input parameter. * @param [out] param2 Output parameter. * * @return Describe what the function returns. * @retval XXX_OK return value. * * @see Related link. * @note Something to note. * @warning Warning. */
4.3 Comments in Codes
For comments in codes, /* */ is suggested to use. And space are recommended to add before and after statements. E.g., Use /* example comment */ instead of /*examplecomment*/
5. Code Format Tool
Windows
AStyle is used to unify the code format. Before running the batch file, make sure AStyle.exe is included in system PATH. The format rules are configured in file config.astyle and all codes will be formated by running astyle.bat.
Reference
Google C++ coding style (good)
https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/scoping/
RDK coding guidelines
https://wiki.rdkcentral.com/display/RDK/Coding+Guidelines
NASA coding style (bad)
http://web.archive.org/web/20190125125043if_/http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
C/C++ coding style by Fred Richards (good)
http://index-of.co.uk/C++/C%20&%20C++%20Programming%20Style%20Guidlines.pdf
Indian Hill C style
https://www.maultech.com/chrislott/resources/cstyle/indhill-cstyle.pdf