Lazy loaded image
🌉开发框架搭建
♟️开发框架03-遵守编程规范
Words 3753Read Time 10 min
2024-12-18
2024-12-18
type
date
slug
category
icon
password

头文件

原则

  1. 头文件中放置接口声明,不放置实现
    1. 内部使用的函数声明不放在头文件中。
    2. 内部使用的宏、枚举、结构定义不应放入头文件中。
    3. 变量定义不应放在头文件中,应放在.c文件中。
    4. 变量的声明尽量不要放在头文件中,亦即尽量不要使用全局变量作为接口。
    5. 必须使用全局变量,也只应当在.c中定义全局变量,在.h中仅声明变量为全局的。
  1. 头文件应职责单一
    1. 头文件不宜过大,职责过多再加上循环依赖,会导致编译时间过长。

规则

  1. 每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。
    1. 如果一个.c文件不需要对外公布任何接口,则其就不应当存在,除非它是程序的入口,如main函数所在的文件。
    2. 本规则反过来并不一定成立。有些特别简单的头文件,如命令ID定义头文件,不需要有对应的.c存在。
    3. 内部使用的函数声明不放在头文件中,放在.c 中声明static
  1. 禁止头文件循环依赖
    1. 头文件循环依赖,指a.h包含b.h,b.h包含c.h,c.h包含a.h之类导致任何一个头文件修改,都 导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。
  1. .c/.h文件禁止包含用不到的头文件
  1. 头文件应当自包含。
    1. 自包含就是任意一个头文件均可独立编译。如果一个文件包含某个头文件,还要包含另外一个头文件才能工作的话,就会增加交流障碍,给这个头文件的用户增添不必要的负担。
  1. 总是编写内部#include保护符(#define 保护)。
    1. 保护符使用唯一名称,命名是PROJECTNAME_PATH_FILENAME_H_;
    2. 不要在受保护部分的前后放置代码或者注释,例外情况:版权声明部分以及头文件的整体注释部分(如阐述此头文件的开发背景、使用注意事项等)可以放在保护符(#ifndef XX_H)前面。
    3. 假定VOS工程的timer模块的timer.h,其目录为VOS/include/timer/timer.h,应按如下方式保护
  1. 禁止在头文件中定义变量。
  1. 只能通过包含头文件的方式使用其他.c提供的接口,禁止在.c中通过extern的方式使用外部函数接口、变量。
  1. 禁止在extern "C"中包含头文件。

    建议

    1. 一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名。为方便外部使用者,建议每一个模块提供一个.h,文件名为目录名。
    1. 如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。说明:降低接口使用者的编写难度。
    1. 同一产品统一包含头文件排列方式。
      1. 说明:常见的包含头文件排列方式:功能块排序、文件名升序、稳定度排序。
      2. 以升序方式排列头文件可以避免头文件被重复包含,如:
        1. 以稳定度排序,建议将不稳定的头文件放在前面,如把产品的头文件放在平台的头文件前面,如下:
          1. 相对来说,product.h修改的较为频繁,如果有错误,不必编译platform.h就可以发现product.h的错误,可以部分减少编译时间。
       

      函数

      原则

      1. 一个函数仅完成一件功能。
      1. 重复代码应该尽可能提炼成函数。

      规则

      1. 避免函数过长,新增函数不超过50行(非空非注释行)。
      1. 避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。
      1. 可重入函数应避免使用共享变量;若需要使用,则应通过互斥手段(关中断、信号量)对其加以保护。
        1. 包含全局变量,不具有可重入性
        2. b. 改进措施
      1. 对参数的合法性检查,由调用者负责还是由接口函数负责,应在项目组/模块内应统一规定。缺省由调用者负责。
      1. 对函数的错误返回码要全面处理。
        1. 立刻检查错误提示
      1. 设计高扇入,合理扇出(小于7)的函数。
      1. 废弃代码(没有被调用的函数和变量)要及时清除

      建议

      1. 函数不变参数使用const。
      1. 函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。
        1. 函数的static局部变量是函数的内部存储器,可能使函数的功能不可预测
        2. 当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类,则返回为错针。
        3. 如下函数,其返回值(即功能)是不可预测的。
      1. 检查函数所有非参数输入的有效性,如数据文件、公共变量等。
        1. 参数输入
        2. 非参数输入:全局变量、数据文件的输入
        1. 函数的参数个数不超过5个。
        1. 除打印类函数外,不要使用可变长参函数。
        1. 在源文件范围内声明和定义的所有函数,除非外部可见,否则应该增加static关键字。
          1. 建议定义一个STATIC宏,在调试阶段,将STATIC定义为static,版本发布时,改为空,以便于后续的打热补丁等操作

        文件与目录

         

        注释规范

         
         

        排版与格式

         
         

        3 命名规范

        通用命名

        目前比较使用的如下几种命名风格:
        1. unix like风格:单词用小写字母,每个单词直接用下划线„_‟分割,例如text_mutex,kernel_text_address。
        1. Windows风格:大小写字母混用,单词连在一起,每个单词首字母大写。不过Windows 风格如果遇到大写专有用语时会有些别扭,例如命名一个读取RFC文本的函数,命令为ReadRFCText,看起来就没有unix like的read_rfc_text清晰了

        原则

        1. 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。
          1. 👍
            int error_number; int number_of_completed_connection;
            👎
            int n; int nerr; int n_comp_conns;
        1. 除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。
          1. 一些常见可以缩写的例子:

        规则

        1. 产品/项目组内部应保持统一的命名风格。 确定Unix like和windows like风格一种,并在产品内部保持一致。

        建议

        1. 用正确的反义词组命名具有互斥意义的变量或相反动作的函数等
          1. 尽量避免名字中出现数字编号,除非逻辑上的确需要编号。
            1. 👍
              #define EXAMPLE_UNIT_TEST_ #define EXAMPLE_ASSERT_TEST_
              👎
              #define EXAMPLE_0_TEST_ #define EXAMPLE_1_TEST_
          1. 标识符前不应添加模块、项目、产品、部门的名称作为前缀。
          1. 平台/驱动等适配代码的标识符命名风格保持和平台/驱动一致。
          1. 重构/修改部分代码时,应保持和原有代码的命名风格一致。

          文件命名

          建议

          1. 文件命名统一采用小写字符。

          变量命名

          规则

          1. 全局变量应增加“g_”前缀。
          1. 静态变量应增加“s_”前缀。
          1. 禁止使用单字节命名变量,但允许定义i、j、k作为局部循环变量。
           

          建议

          1. 不建议使用匈牙利命名法。
            1. 添加变量类型,降低了变量的可读性
            2. 修改变量类型定义后,所有使用该变量的地方都需要修改。
          1. 使用名词或者形容词+名词方式命名变量。

          函数命名

          建议

          1. 函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。
            1. 函数指针除了前缀,其他按照函数的命名规则命名。

              宏的命名

              规则

              1. 对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线 “_” 的方式命名(枚举同样建议使用此方式定义)。
                1. 除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线“_”开头和结尾。

                变量

                原则

                1. 一个变量只有一个功能,不能把一个变量用作多种用途。
                  1. 👍
                    WORD DelRelTimeQue(void) { WORD Ret; WORD Locate;
                    Locate = 3; Ret = DeleteFromQue(Locate);
                    return Ret; }
                    👎
                    WORD DelRelTimeQue(void) { WORD Locate;
                    Locate = 3; Locate = DeleteFromQue(Locate); /* Locate具有两种功能:位置和函数 DeleteFromQue的返回值 */ return Locate; }
                1. 结构功能单一;不要设计面面俱到的数据结构。
                  1. 相关的一组信息才是构成一个结构体的基础,结构的定义应该可以明确的描述一个对象,而不是一组相关性不强的数据的集合。
                1. 不用或者少用全局变量。

                规则

                1. 防止局部变量与全局变量同名。
                1. 通讯过程中使用的结构,必须注意字节序。
                  1. 通讯报文中,字节序是一个重要的问题,我司设备使用的cpu类型复杂多样,大小端、32位/64位的处理器也都有,如果结构会在报文交互过程中使用,必须考虑字节序问题。
                1. 严禁使用未经初始化的变量作为右值。

                建议

                1. 构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的全局变量,防止多个不同模块或函数都可以修改、创建同一全局变量的现象。
                1. 使用面向接口编程思想,通过API访问数据:如果本模块的数据需要对外部模块开放,应提供接口函数来设置、获取,同时注意全局数据的访问互斥。
                1. 在首次使用前初始化变量,初始化的地方离使用的地方越近越好。
                1. 明确全局变量的初始化顺序,避免跨模块的初始化依赖。
                1. 尽量减少没有必要的数据类型默认转换与强制转换。
                 
                 

                CLion 配置方法

                 
                 

                MISRA

                1. MISRA-Example-Suite/D_01_01.c at master · jubnzv/MISRA-Example-Suite (github.com)
                1. MISRA C 2012标准学习与理解 - 明明1109 - 博客园 (cnblogs.com)
                1. MISAR C 2012 (notion.site)
                 

                引用

                1. MISRA(官网)
                1. MISRA C:2012 Compliance Summary Tables - MATLAB & Simulink - MathWorks 中国
                1. MISRA C 2012标准学习与理解 - 明明1109 - 博客园 (cnblogs.com)
                1. MISRA C:2012 Compliance (keil.com)
                1. MISRA checks supported in CLion | Knowledge Base
                1. MISRA类似编程规范的测试题目,哪里可以找到? - 开发环境 - 硬汉嵌入式论坛 - Powered by Discuz! (armbbs.cn)
                 
                上一篇
                开发框架02-开发环境搭建
                下一篇
                开发框架04-集成单元测试框架

                Comments
                Loading...