C/C++注释规范
C/C++注释规范
下载国外的源代码,往往能看到附带的说明文档,文档都有详细的说明,大部分文档都可以通过doxygen这个跨平台软件生成,doxygen并不能随便读取你的C++的注释,必须按照一定的规则才能生成,所以在编写代码时,一定要按照标准写注释,否则会为以后带来许多麻烦。
下面介绍C++的标注写法,c++不推荐c语言式的/* */风格注释,这里,除了文件头使用这种注释外其余到使用C++风格的注释。
下面具体介绍各部分的注释规范:
简单注释
- 单行注释:
///
或者//!
- 多行注释:
/**
或者/*!
文件头
/*!
* \file Ctext.h
* \brief 概述
*
*详细概述
*
* \author 作者名字
* \version 版本号(maj.min,主版本.分版本格式)
* \date 日期
*/
命名空间
/// \brief 命名空间的简单概述
///
///命名空间的详细概述
namespace text
{
……
}
类说明
/// \brief Ctext的doxygen测试
///
/// 作doxygen测试用
class Ctext
{
}
函数标注
方法一:
/// \brief 函数简要说明-测试函数
/// \param n1 参数1
/// \param c2 参数2
/// \return 返回说明
bool text(int n1,Ctext c2);
方法二:
/// \brief 函数简要说明-测试函数
///
/// 函数详细说明,这里写函数的详细说明信息,说明可以换行
/// ,如这里所示,同时需要注意的是详细说明和简要说明之间必须空一行
/// ,详细说明之前不需要任何标识符
/// \param n1 参数1说明
/// \param c2 参数2说明
/// \return 返回说明
/// \see text
bool text2(int n1,Ctext c2);
变量及枚举
int m_a; ///< 成员变量1m_a说明
double m_b; ///< 成员变量2m_b说明
/// \brief 成员变量m_c简要说明
///
/// 成员变量m_c的详细说明,这里可以对变量进行
///详细的说明和描述,具体方法和函数的标注是一样的
float m_c;
/// \brief xxx枚举变量的简要说明
///
/// xxx枚举变量的详细说明--枚举变量的详细说明和函数的详细说明
///的写法是一致的。每个枚举变量下可以进行单独说明
enum{
em_1,///< 枚举值1的说明
em_2,///< 枚举值2的说明
em_3 ///< 枚举值3的说明
};
其他关键字
命令 | 生成字段 | 说明 |
---|---|---|
@see |
参考 | |
@class |
引用类 | 用于文档生成连接 |
@var |
引用变量 | 用于文档生成连接 |
@enum |
引用枚举 | 用于文档生成连接 |
@code |
代码块开始 | 与@endcode 成对使用 |
@endcode |
代码块结束 | 与@code 成对使用 |
@bug |
缺陷 | 链接到所有缺陷汇总的缺陷列表 |
@todo |
TODO | 链接到所有TODO汇总的TODO列表 |
@example |
使用例子说明 | |
@remarks |
备注说明 | |
@pre |
函数前置条件 | |
@deprecated |
函数过时说明 |
其他Doxygen的关键字参见Doxygen文档:
http://www.doxygen.nl/manual/index.html
QtCreator中使用
在QtCreator中自带Doxygen补全模块,开启如下图
自动补全如下:在变量名或函数前一行输入///
然后回车,系统会自动生成
///
/// \brief 变量名或函数名及参数或类名
///
将Readme.md作为文档首页
readme.md格式如下
Title {#mainpage}
================
具体详细内容
Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C、C++、Java、Objective-C和IDL语言,部分支持PHP、C#。鉴于Doxygen良好的注释风格,故基于Doxygen以形成自己的注释规范。
1.标注总述
//-------------------------------------------------------------------
// Platform Defines
//-------------------------------------------------------------------
enum
{
OST_PLATFORM_WIN32 = 1,
OST_PLATFORM_LINUX_X86 = 2,
OST_PLATFORM_LINUX_ARM = 3,
OST_PLATFORM_ANDROID = 4,
OST_PLATFORM_MACOSX = 5,
};
//-------------------------------------------------------------------
// API Export/Import Macros
//-------------------------------------------------------------------
/** Indicates an exported and imported shared library function. */
#define OST_API_EXPORT __declspec(dllexport)
#define OST_API_IMPORT __declspec(dllimport)
//-------------------------------------------------------------------
// Digital Image Macros
//-------------------------------------------------------------------
#define OST_PI 3.141592653589793f
#define OST_RGB2GRAY(r, g, b) ( ((b) * 117 + (g) * 601 + (r) * 306) >> 10 )
//-------------------------------------------------------------------
// date and time at compile time
//-------------------------------------------------------------------
#define OST_TIMESTAMP __DATE__ " " __TIME__
2. 文件头的标注
/*****************************************************************************
* OpenST Basic tool library *
* Copyright (C) 2014 Henry.Wen renhuabest@163.com. *
* *
* This file is part of OST. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License *
* along with OST. If not, see <http://www.gnu.org/licenses/>. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* @file Example.h *
* @brief 对文件的简述 *
* Details. *
* *
* @author Henry.Wen *
* @email renhuabest@163.com *
* @version 1.0.0.1(版本号) *
* @date renhuabest@163.com *
* @license GNU General Public License (GPL) *
* *
*----------------------------------------------------------------------------*
* Remark : Description *
*----------------------------------------------------------------------------*
* Change History : *
* <Date> | <Version> | <Author> | <Description> *
*----------------------------------------------------------------------------*
* 2014/01/24 | 1.0.0.1 | Henry.Wen | Create file *
*----------------------------------------------------------------------------*
* *
*****************************************************************************/
3.命名空间
/**
* @brief 命名空间的简单概述 \n(换行)
* 命名空间的详细概述
*/
namespace OST
{
}
4. 类、结构、枚举标注
/**
* @brief 类的简单概述 \n(换行)
* 类的详细概述
*/
class Example
{
};
枚举类型定义、结构体类型定义注释风格类似
/**
* @brief 简要说明文字
*/
typedef struct 结构体名字
{
成员1, /*!< 简要说明文字 */ or ///<说明, /**<说明 */
成员2, /*!< 简要说明文字 */ or ///<说明, /**<说明 */
成员3, /*!< 简要说明文字 */ or ///<说明, /**<说明 */
}结构体别名;
5. 函数注释原则
/**
* @brief 函数简要说明-测试函数
* @param index 参数1
* @param t 参数2 @see CTest
*
* @return 返回说明
* -<em>false</em> fail
* -<em>true</em> succeed
*/
bool Test(int index, const CTest& t);
note:指定函数注意项事或重要的注解指令操作符 note格式如下: @note 简要说明 retval:指定函数返回值说明指令操作符。(注:更前面的return有点不同.这里是返回值说明) retval格式如下: @retval 返回值 简要说明 pre:指定函数前置条件指令操作符 pre格式如下: @pre 简要说明 par:指定扩展性说明指令操作符讲。(它一般跟code、endcode一起使用 ) par格式如下: @par 扩展名字 code、endcode:指定 code、endcode格式如下: @code 简要说明(内容) @endcode see:指定参考信息。 see格式如下: @see 简要参考内容 deprecated:指定函数过时指令操作符。 deprecated格式如下: @deprecated 简要说明 调试Bug说明 解决的bug说明,@bug 警告说明 (warning) 定义一些关于这个函数必须知道的事情,@warning 备注说明 (remarks) 定义一些关于这个函数的备注信息,@remarks 将要完成的工作 (todo) 说明哪些事情将在不久以后完成,@todo 使用例子说明 (example) 例子说明,@example example.cpp
/**
* @brief 打开文件 \n
* 文件打开成功后,必须使用::CloseFile函数关闭
* @param[in] fileName 文件名
* @param[in] fileMode 文件模式,可以由以下几个模块组合而成:
* -r读取
* -w 可写
* -a 添加
* -t 文本模式(不能与b联用)
* -b 二进制模式(不能与t联用)
* @return 返回文件编号
* --1表示打开文件失败(生成时:.-1)
* @note文件打开成功后,必须使用::CloseFile函数关闭
* @par 示例:
* @code
* //用文本只读方式打开文件
* int ret = OpenFile("test.txt", "a");
* @endcode
* @see 函数::ReadFile::CloseFile (“::”是指定有连接功能,可以看文档里的CloseFile变成绿,点击它可以跳转到CloseFile.)
* @deprecated由于特殊的原因,这个函数可能会在将来的版本中取消
*/
int OpenFile(const char* fileName, const char* fileMode);
/**
* @brief 关闭文件
* @param [in] file 文件
*
* @retval 0 成功
* @retval -1 失败
* @pre file 必须使用OpenFile的返回值
*/
int CloseFile(int file);
-:生成一个黑心圆. -#:指定按顺序标记。 :::指定连接函数功能。(注:空格和“:”有连接功能,但建议还是使用”::”。只对函数有用。) 它们格式如下: (-和::例子前面有了,就介绍-#例子。) - 简要说明 -# 简要说明 ::函数名 例:
/**
* @param [in] person 只能输入以下参数:
* -# a:代表张三 // 生成 1. a:代表张三
* -# b:代表李四 // 生成 2. b:代表李四
* -# c:代表王二 // 生成 3. c:代表王二
*/
void GetPerson(int p);
6. 变量注释
/// 简述
/** 详细描述. */
或者
//! 简述
//! 详细描述
//! 从这里开始
int m_variable_1; ///< 成员变量m_variable_1说明
int m_variable_2; ///< 成员变量m_variable_1说明
/**
* @brief 成员变量m_c简要说明
*
* 成员变量m_variable_3的详细说明,这里可以对变量进行
* 详细的说明和描述,具体方法和函数的标注是一样的
*/
bool m_variable_3;
如果变量需要详细说明的可已按照m_varibale_3的写法写,注意,m_variable_2和m_variable_3之间一定需要空行,否则会导致m_variable_2的简述消失 7. 模块标注 模块定义格式:
/**
* @defgroup 模块名 页的标题名 (模块名只能英文,这个可以随便取.在一个源文件里不能相同)
* @{ (跟c语言{一样起作用域功能)
*/
… 定义的内容 …
/** @} */
例:
/**
* @defgroup HenryWen Example.cpp
* @{
*/
… 定义的内容 …
/** @} */
8. 分组标注 分组定义格式:
/**
* @name 分组说明文字
* @{
*/
… 定义的内容 …
/** @} */
例:
/**
* @name PI常量
* @{
*/
#define PI 3.1415926737
/** @} */
/**
* @name 数组固定长度常量
* @{
*/
const int g_ARRAY_MAX = 1024;
/** @} */
来源 https://zhuanlan.zhihu.com/p/267645803
编码风格对于软件开发者而言十分重要,对大型的开发团队更是如此,每个公司也都有自己的风格规定。在这里分享一套我在 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 <PLATFORM>_<FILE>_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. <unistd.h>, <stdlib.h>.
- 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 is
xxx_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
<stdint.h>
(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.c
static 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
Doxygen
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 __cplusplus
extern "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)
2. RDK coding guidelines (good)
3. NASA coding style (bad)
4. C/C++ coding style by Fred Richards (good)
5. Indian Hill C style
来源 https://zhuanlan.zhihu.com/p/314971283
在编写大量代码时,或者与多人协作进行开发时,文字记录很重要(文档或注释),尤其对于开发者本人回顾之前写过的代码和 code reviewer 查看。目前,代码中的注释进是程序员们最经常使用的记录方法。但是,由于每个人的注释风格不同,有些开发者甚至对API并不进行任何注释描述,导致很多影响生产效率的问题,也增加了软件维护的成本。很多人对于怎样写注释也会困惑和反感。因此,使用一些代码文档工可以帮助这个开发流程高效、规范地进行。
使用这种工具我个人认为最大的帮助是可以节省时间,并提高生产力:
- 不用去构思如何去写注释,用哪一种风格去写,从而专注于构思代码。
- 减少看其他人代码的时间成本。
Doxygen 就是这样一种编写软件参考文档的工具。该文档是直接以注释的形式写在代码中的,因此比较容易修改和查看。而且对于代码里的注释,Doxygen还可以为C++项目生成html,Latex和PDF的文档。
虽然使用过Doxygen的开发者可能并不会经常阅读由Doxygen生成的那些文档,而是更加倾向于阅读源代码里的注释。但是并不妨碍Doxygen成为一款很受欢迎而且高效的代码注释工具,至少我个人很喜欢Doxygen对于注释的种种规范。
关于如何使用Dxygen的适用方法,可以参照官方的教程,不会有比这个更加权威并且详细的说明了:https://www.doxygen.nl/manual/index.html。
在之前分享过的C/C++ Coding Style(https://zhuanlan.zhihu.com/p/267645803)中,我介绍了使用Doxygen进行代码注释的一些风格,在这里详细介绍一些我经常使用的Doxygen属性。
一个例子
例如一个头文件中:
/*****************************************************************************
* Portfolio Info
****************************************************************************/
/**
* @file doxygen.h
* @brief File containing example of doxygen usage for quick reference.
*
* Here typically goes a more extensive explanation of what the header
* defines. Doxygens tags are words preceeded by either a backslash @\\
* or by an at symbol @@.
*
* @author Chris Wu
* @date 24 Oct 2019
* @see <http://www.doxygen.nl/manual/index.html>
*/
/** @addtogroup DOXYGEN_API
* @brief Doxygen api example.
*
* Detailed api description.
*
* @{
*/
#ifndef _TEMP_DOXYGEN_H
#define _TEMP_DOXYGEN_H
#ifdef __cplusplus
extern "C" {
#endif
/* INCLUDE FILES */
#include <stdint.h>
//#include <system_header2.h>
//#include "local_header1.h"
//#include "local_header2.h"
/* GLOBAL DEFINES */
/**
* @brief Use brief, otherwise the index won't have a brief explanation.
*
* Detailed explanation.
*/
typedef enum eEnumMode
{
ENUM_FIRST, /**< Some documentation for first. */
BOXENUM_SECOND, /**< Some documentation for second. */
BOXENUM_ETC /**< Etc. */
} tEnumMode;
/**
* @brief Use brief, otherwise the index won't have a brief explanation.
*
* Detailed explanation.
*/
typedef struct BoxStruct
{
int a; /**< Some documentation for the member BoxStruct#a. */
int b; /**< Some documentation for the member BoxStruct#b. */
double c; /**< Etc. */
} tBoxStruct;
/* GLOBAL VARIABLES */
extern int giValue;
/* GLOBAL FUNCTIONS */
/**
* @brief Example showing how to document a function with Doxygen.
*
* Description of what the function does. This part may refer to the parameters
* of the function, like @p param1 or @p param2. A word of code can also be
* inserted like @c this which is equivalent to <tt>this</tt> and can be useful
* to say that the function returns a @c void or an @c int. If you want to have
* more than one word in typewriter font, then just use @<tt@>.
* We can also include text verbatim,
* when the language is not the one used in the current source file (but
* <b>be careful</b> as this may be supported only by recent versions
* of Doxygen). By the way, <b>this is how you write bold text</b> or,
* if it is just one word, then you can just do @b this.
*
* @param [in] param1 Description of the first parameter of the function.
* @param [out] param2 The second one, which follows @p param1, and represents output.
*
* @return Describe what the function returns.
* @retval XXX_OK if successful.
*
* @see doxygen_theSecondFunction
* @see Box_The_Last_One
* @see <http://website/>
* @note Something to note.
* @warning Warning.
*/
int doxygen_theFirstFunction(int param1, int param2);
/**
* @brief A simple stub function to show how links do work.
*
* Links are generated automatically for webpages (like <http://www.google.com>)
* and for structures, like sBoxStruct. For typedef-ed types use
* #tBoxStruct.
* For functions, automatic links are generated when the parenthesis () follow
* the name of the function, like doxygen_theFirstFunction().
* Alternatively, you can use #doxygen_theFirstFunction.
* @return @c NULL is always returned.
*/
void doxygen_theSecondFunction(void);
#ifdef __cplusplus
}
#endif
#endif /* _TEMP_DOXYGEN_H */
/** @}*/
版权声明注释
/*****************************************************************************
* Portfolio Info
****************************************************************************/
我会把项目的版权声明信息放在这。
文件描述注释
/**
* @file header.h
* @brief Brief file introduction.
*
* Detailed file introduction.
*
* @author Name
* @date day month year
* @see Related link.
*/
在这里列出这个文件的名字,和一些基本信息:
- @file: 文件名
- @brief:文件一句话介绍
- @author:文件作者
- @date:修改日期
- @see:额外的一些参考信息,比如有用过的链接
API Group
/** @addtogroup DOXYGEN_API
* @brief Doxygen api example.
*
* Detailed api description.
*
* @{
*/
- API codes...
/** @}*/
这两段代码搭配使用,一前一后,中间包含API代码。这部分定义了这个文件的API group,可以在Doxygen生成的文件中查看到其中包含的所有API group(比如变量,类,函数)信息。
变量前的注释
/**
* @brief Use brief, otherwise the index won't have a brief explanation.
*
* Detailed explanation.
*/
typedef struct BoxStruct
{
int a; /**< Some documentation for the member BoxStruct#a. */
int b; /**< Some documentation for the member BoxStruct#b. */
double c; /**< Etc. */
} tBoxStruct;
对于一些需要说明的变量,可以在变量前加上一段Doxygen注释,方便度代码的人查看,也可以声称在比如HTML等文档中。
API 函数注释
/* GLOBAL FUNCTIONS */
/**
* @brief Example showing how to document a function with Doxygen.
*
* Description of what the function does. This part may refer to the parameters
* of the function, like @p param1 or @p param2. A word of code can also be
* inserted like @c this which is equivalent to <tt>this</tt> and can be useful
* to say that the function returns a @c void or an @c int. If you want to have
* more than one word in typewriter font, then just use @<tt@>.
* We can also include text verbatim,
* when the language is not the one used in the current source file (but
* <b>be careful</b> as this may be supported only by recent versions
* of Doxygen). By the way, <b>this is how you write bold text</b> or,
* if it is just one word, then you can just do @b this.
*
* @param [in] param1 Description of the first parameter of the function.
* @param [out] param2 The second one, which follows @p param1, and represents output.
*
* @return Describe what the function returns.
* @retval XXX_OK if successful.
*
* @see doxygen_theSecondFunction
* @see Box_The_Last_One
* @see <http://website/>
* @note Something to note.
* @warning Warning.
*/
int doxygen_theFirstFunction(int param1, int param2);
对于所有头文件的函数,都需要进行函数注释。
- @param:标记变量 [in] [out]表示输入输出方向
- @return:返回值描述
- @retval:具体返回值及其含义
- @see:link信息
- @note:备注信息
- @warning:需要函数使用者注意的信息,比如:功能未经完全验证
总结
我对自己的要求是,对于 public 头文件中的所有信息,都应该进行详细的注释,方便使用者查看。而在代码源文件中可以不详细注释,自己可以理解。但是也需要按照Doxygen的格式列出基本信息方便回顾代码的时候提醒自己,让自己了解自己当时在想些什么,为什么要这么做。
对于一个开发团队,尤其是大公司,都会有严格规定的标准,包括代码风格,各种git hook,还有类似Doxygen这种文档工具。有些工程师会觉得这些“标准”很繁琐,很难要求自己遵守。但是不可否认的是,各种代码标准的目的不是以折磨程序员为乐趣,而是为了提高程序员的生产力,提高代码的可读性,可维护性,可靠性。
但是有时候,为了追求标准化而去不断强调“标准”这个概念,甚至花费大量的时间精力去专注在“标准”们上也是很荒唐的。所以无论我们使用哪些“标准”,参考各大开发团队的标准,形成一套适合自己团队的开发规范即可,内容永远大于形式。
========== End