关于MISRA-C编程规范的一些思考

关于MISRA-C编程规范的一些思考

1: 对语言子集的理解

编程语言定义了这个语言的全部特性,但是这些特性并不都是安全的。例如C语言中的指针:C语言本身并没有规定一定不能读取或者写入哪个地址。虽然一些编译器可能会对指针的访问作出限制或者提示,但这并不是语言本身的定义。那么,通过限制对语言部分特性的使用,可以有效降低由不恰当使用这些特性带来的质量风险,也就是所谓语言子集的概念。
典型的功能安全标准也规定了对语言子集的使用,以IEC61508为例:
在这里插入图片描述

2: 强制规则是否一定要遵守

答案是否定的。MISRA-C允许对强制规则进行所谓的背离,只是如果发生了背离,需要提供相关的描述和认可。其实这也是可以理解的。因为MISRA-C中的部分规则限定过于严苛,如果完全遵守,那写出来的代码可能看起来非常别扭,或者干脆就没法写。本文将在下面给出一些实例。


3: 对规则14.7的理解

规则 14.7 (强制) : 一个函数在其结尾应该有单一的退出点。
这一条和某些功能安全标准上倡导的“防御式编程”是冲突的。防御式编程,讲究的是对异常情况进行早期判断,并及时进行错误处理或者退出执行过程,一种常见的方式是:

int Func(int *p1, int *p2)
{
    if (NULL == p1)
    {
        /* TODO: 日志记录或者错误处理 */
        return -1;
    }

    if (NULL == p2)
    {
        /* TODO: 日志记录或者错误处理 */
        return -1;
    }

    /* ......... */

    return -1;
}

如果遵循14.7 ,那么这个函数的写法就要换成一层层判断嵌套的方式,它的可读性和可维护性就会差很多。所以,14.7这个规则,在实际应用上,往往是背离的。

4: 对规则16.1的理解

规则 16.1 (强制):函数定义不得带有可变数量的参数。
这条规则说的是函数不能使用变参。但是,在嵌入式开发领域中,变参有时候是不可避免的。
在这里插入图片描述
上面是AutoSar-CP标准体系中,对操作系统的定义。其中就有部分接口使用了可变参数。当然这里在开发的时候也要记录为背离。

5: 对规则11.2的理解

规则 11.2 (强制): 对象指针和其他除整型之外的任何类型指针之间、对象指针和其他类型对象的指针之间、对象指针和 void 指针之间不能进行转换。
最后一条“对象指针和 void 指针之间不能进行转换”:个人认为这一条不能照本宣科。因为void为C语言提供了一定的“泛型”能力,这使得上层软件可以拥有良好的硬件可移植性,例如:

void *memset (void *buffer, int c, size_t num);

如果对象指针和 void 指针之间不能进行转换,那么就必须显示定义memset中缓冲区的数据类型,这就显著降低了这个接口在不同硬件之间的可移植性。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庄周梦蝶梦庄周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值