• 注释
    • 注释风格
    • 文件头注释
      • 规则4.2.1 文件头注释必须包含版权许可
    • 函数头注释
      • 规则4.3.1 禁止空有格式的函数头注释
    • 代码注释
      • 规则4.4.1 代码注释放于对应代码的上方或右边
      • 规则4.4.2 注释符与注释内容间要有1空格;右置注释与前面代码至少1空格
      • 规则4.4.3 不用的代码段直接删除,不要注释掉
      • 建议4.4.1 正式交付给客户的代码不能包含 TODO/TBD/FIXME 注释

    注释

    一般的,尽量通过清晰的架构逻辑,好的符号命名来提高代码可读性;需要的时候,才辅以注释说明。注释是为了帮助阅读者快速读懂代码,所以要从读者的角度出发,按需注释

    注释内容要简洁、明了、无二义性,信息全面且不冗余。

    注释跟代码一样重要。写注释时要换位思考,用注释去表达此时读者真正需要的信息。在代码的功能、意图层次上进行注释,即注释解释代码难以表达的意图,不要重复代码信息。修改代码时,也要保证其相关注释的一致性。只改代码,不改注释是一种不文明行为,破坏了代码与注释的一致性,让阅读者迷惑、费解,甚至误解。

    注释风格

    在 C++ 代码中,使用/ ///都是可以的。按注释的目的和位置,注释可分为不同的类型,如文件头注释、函数头注释、代码注释等等;同一类型的注释应该保持统一的风格。

    注意:本文示例代码中,大量使用 '//' 后置注释只是为了更精确的描述问题,并不代表这种注释风格更好。

    文件头注释

    规则4.2.1 文件头注释必须包含版权许可

    1. /*
    2. * Copyright (c) [2019] [name of copyright holder]
    3. * [Software Name] is licensed under the Mulan PSL v1.
    4. * You can use this software according to the terms and conditions of the Mulan PSL v1.
    5. * You may obtain a copy of Mulan PSL v1 at:
    6. * http://license.coscl.org.cn/MulanPSL
    7. * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
    8. * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
    9. * PURPOSE.
    10. * See the Mulan PSL v1 for more details.
    11. */

    函数头注释

    规则4.3.1 禁止空有格式的函数头注释

    并不是所有的函数都需要函数头注释;函数签名无法表达的信息,加函数头注释辅助说明;

    函数头注释统一放在函数声明或定义上方,使用如下风格之一:使用//写函数头

    1. // 单行函数头
    2. int Func1(void);
    3. // 多行函数头
    4. // 第二行
    5. int Func2(void);

    使用/ /写函数头

    1. /* 单行函数头 */
    2. int Func1(void);
    3. /*
    4. * 另一种单行函数头
    5. */
    6. int Func2(void);
    7. /*
    8. * 多行函数头
    9. * 第二行
    10. */
    11. int Func3(void);

    函数尽量通过函数名自注释,按需写函数头注释。不要写无用、信息冗余的函数头;不要写空有格式的函数头。

    函数头注释内容可选,但不限于:功能说明、返回值,性能约束、用法、内存约定、算法实现、可重入的要求等等。模块对外头文件中的函数接口声明,其函数头注释,应当将重要、有用的信息表达清楚。

    例:

    1. /*
    2. * 返回实际写入的字节数,-1表示写入失败
    3. * 注意,内存 buf 由调用者负责释放
    4. */
    5. int WriteString(const char *buf, int len);

    坏的例子:

    1. /*
    2. * 函数名:WriteString
    3. * 功能:写入字符串
    4. * 参数:
    5. * 返回值:
    6. */
    7. int WriteString(const char *buf, int len);

    上面例子中的问题:

    • 参数、返回值,空有格式没内容
    • 函数名信息冗余
    • 关键的 buf 由谁释放没有说清楚

    代码注释

    规则4.4.1 代码注释放于对应代码的上方或右边

    规则4.4.2 注释符与注释内容间要有1空格;右置注释与前面代码至少1空格

    代码上方的注释,应该保持对应代码一样的缩进。选择并统一使用如下风格之一:使用//

    1. // 这是单行注释
    2. DoSomething();
    3. // 这是多行注释
    4. // 第二行
    5. DoSomething();

    使用/' '/

    1. /* 这是单行注释 */
    2. DoSomething();
    3. /*
    4. * 另一种方式的多行注释
    5. * 第二行
    6. */
    7. DoSomething();

    代码右边的注释,与代码之间,至少留1空格,建议不超过4空格。通常使用扩展后的 TAB 键即可实现 1-4 空格的缩进。

    选择并统一使用如下风格之一:

    1. int foo = 100; // 放右边的注释
    2. int bar = 200; /* 放右边的注释 */

    右置格式在适当的时候,上下对齐会更美观。对齐后的注释,离左边代码最近的那一行,保证1-4空格的间隔。例:

    1. const int kConst = 100; /* 相关的同类注释,可以考虑上下对齐 */
    2. const int kAnotherConst = 200; /* 上下对齐时,与左侧代码保持间隔*/

    当右置的注释超过行宽时,请考虑将注释置于代码上方。

    规则4.4.3 不用的代码段直接删除,不要注释掉

    被注释掉的代码,无法被正常维护;当企图恢复使用这段代码时,极有可能引入易被忽略的缺陷。正确的做法是,不需要的代码直接删除掉。若再需要时,考虑移植或重写这段代码。

    这里说的注释掉代码,包括用 / / 和 //,还包括 #if 0, #ifdef NEVER_DEFINED 等等。

    建议4.4.1 正式交付给客户的代码不能包含 TODO/TBD/FIXME 注释

    TODO/TBD 注释一般用来描述已知待改进、待补充的修改点FIXME 注释一般用来描述已知缺陷它们都应该有统一风格,方便文本搜索统一处理。如:

    1. // TODO(<author-name>): 补充XX处理
    2. // FIXME: XX缺陷