0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MISRA C编写更安全清晰的C代码

李静 来源:sayhealer 作者:sayhealer 2022-07-15 14:36 次阅读

嵌入式开发人员经常抱怨没有一种编程语言能完美满足他们的特定需求。在某种程度上,这种情况并不令人惊讶,因为尽管有很多开发人员在开发嵌入式应用程序,但他们仍然只是世界编程社区的一小部分。然而,一些语言在开发时就考虑到了嵌入式。值得注意的例子是 PL/M、Forth 和 Ada,它们都已被广泛使用,但从未被普遍接受。其他语言,如 Rust,正在获得支持,但尚未成为主流。几乎被普遍采用的折衷方案是 C。如何才能使这种折衷方案最有效地发挥作用?

C 语言简洁、富有表现力且功能强大。它为程序员提供了编写高效、可读和可维护的代码的方法。所有这些功能都说明了它的受欢迎程度。不幸的是,该语言还使粗心的开发人员能够编写危险的、不安全的代码,这些代码可能会在开发项目的所有阶段和部署中导致严重的问题。对于安全性和/或安全性是主要优先事项的应用程序,语言的这些缺点是一个主要问题。

正是在这种背景下,在 1990 年代后期,汽车工业软件可靠性协会 (MISRA) 推出了一套在车辆系统中使用 C 的指南,即后来的 MISRA C。从那时起,该指南一直在稳步推进。完善,不时发布更新。还建立了使用 C++ 的类似方法。尽管该指南最初针对的是汽车软件开发人员,但很快就意识到它们同样适用于安全至关重要的许多其他应用领域,并且该标准现在已被许多行业广泛采用。

尽管 MISRA C 不是风格指南——事实上,许多用户在应用风格指南和标准的同时——许多规则也促进了清晰、可读、可维护的代码的编写。这是非常有益的,因为易于理解的代码不太可能包含细微的错误或未定义的行为。

MISRA C 的完整详细信息可从https://misra.org.uk获得,并且有许多可用的工具支持该方法。

我将在这里简单介绍一下指南。我的参考资料来自 MISRA C:2012 第三版,第一版。MISRA C 正在不断审查中,增量更改解决了指南的清晰度和准确性以及对新版本 C 语言标准的支持。尽管细节发生了变化,但整体理念和方法没有变化。

规则 13.2 – 在所有允许的评估顺序下,表达式的值及其持续的副作用应相同

C 语言标准在表达式中的求值顺序方面为编译器提供了非常广泛的自由度。因此,任何对评估顺序敏感的代码都是依赖于编译器和依赖于编译器的代码,因此应始终将其视为不安全的。

例如,递增和递减运算符的使用可能会很麻烦:

val = n++ + arr[n];

访问arr的哪个元素程序员是否期望用于索引数组的n的值是在增量之前还是之后?尽管看起来好像在数组索引之前执行了增量,但它假设了左右表达式评估,这不是一个有效的假设。所以,代码不清楚,应该重写如下:

val = n + arr[n+1];
n++;

或者

val = n++;
val += arr[n];

甚至

val = n;
n++;
val += arr[n];

您选择哪个选项取决于个人风格。它们都执行相同的操作,事实上,优化编译器很可能会生成完全相同的代码。

一个表达式中使用的多个函数调用可能会出现类似的问题。函数调用可能具有影响另一个函数的副作用。例如:

val = fun1() + fun2();

在这种情况下,如果任何一个函数都可以影响另一个函数的结果,那么代码就是模棱两可的。要编写安全代码,必须消除任何可能的歧义:

val = fun1();
val += fun2();

现在很清楚fun1()是首先执行的。

规则 17.2 – 函数不得直接或间接调用自己

有时,表达算法的一种优雅方式是使用递归。但是,除非对递归进行非常严格的控制,否则存在堆栈溢出的危险,这反过来又会导致非常难以定位错误。在安全关键代码中,应避免递归。

Rule 19.2 – The union keyword should not be used

Although C is a typed language, typing is not very strictly enforced, and developers may be tempted to override typing to “simplify” their code. Adhering to the constraints of data types is essential to create safe code, as any attempts to get around data types can produce undefined results. The union keyword can be used for a number of purposes, which generally result in unclear code, but can also be a means to circumvent typing.

One example would be using a union to “take apart” an unsigned integer, thus:

union e
{
unsigned int ui;
unsigned char a[4];
}f;

在这种情况下, ui的每个字节都可以作为 a 的元素访问但是,我们不能确定a[0]是否是最不重要的字节,因为这是一个实现问题。(本质上与处理器的字节序有关。)替代方法可能是使用移位和屏蔽,因此:

unsigned char getbyte(unsigned int input, unsigned int index)
{
input >>= (index * 8);
返回输入 & 0xff;
}

有人可能会争辩说,这些规则(以及 MISRA C 的大多数,如果不是全部的话)只是常识,任何优秀的程序员都会采用这种方法。这可能是真的,但一套明确的指导方针让机会更少。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4983

    文章

    18291

    浏览量

    288539
  • C语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128811
  • MISRA
    +关注

    关注

    0

    文章

    18

    浏览量

    6891
收藏 人收藏

    评论

    相关推荐

    编写高质量C语言代码

    编写高质量C语言代码 编写高质量C语言代码 编写高质
    发表于 07-31 17:47

    MISRA C 2012 学习资料

    `MISRA C 学习资料 `
    发表于 09-17 14:55

    MISRA-C-2004_工业标准的C编程规范_中文版

    MISRA-C-2004_工业标准的C编程规范_中文版
    发表于 06-13 11:47

    微软开源了一个安全C 语言版本:Checked C

    微软开源了 Checked C[1] ,这是一个 C 语言的扩展版本,可以用于解决 C 语言中的一系列安全相关的隐患。正如其名字所示,Checked
    发表于 06-20 17:26

    华为C语言编程规范

    规范制定了编写C语言程序的基本原则、规则和建议。从代码清晰、简洁、可测试、安全、程序效率、可移植各个方面对
    发表于 11-24 09:38

    基于C#编写图书管理系统设计(代码).doc

    基于C#编写图书管理系统设计(代码).doc
    发表于 06-17 16:39

    DragonBoard 410c代码编写

    410c中进行了代码编写,并成功对代码进行编译与运行,输出了hello world文字。 如果各位对eclipse感兴趣,也可以看我接下来
    发表于 09-21 10:10

    什么是C语言?

    可以编写系统软件。C语言的特点:优点1.C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试。2.
    发表于 01-07 16:24

    MISRA C编程规范标准有什么规则要求?

    如何衡量代码是否满足某些标准?MISRA C编程规范标准有什么规则要求?
    发表于 04-19 07:20

    如何用STM32CubeMX生成底层代码代码C++的编写要注意哪些事项?

    如何用STM32CubeMX生成底层代码?单片机代码如何进行IDE的C++配置?代码C++的编写
    发表于 07-01 06:22

    怎样去编写STC89C52蜂鸣器的C程序代码

    STC89C52蜂鸣器的实验原理是什么?怎样去编写STC89C52蜂鸣器的C程序代码
    发表于 10-22 08:21

    如何在底层编写汇编代码或者C语言代码

    在2000年前后,嵌入式软件工程师有着一套非常具体的技能,他们通常是电气工程师,不仅了解底层硬件的工作原理,还可以在底层编写汇编代码或者C语言代码,以使系统满足实时需求。...
    发表于 12-15 06:28

    如何编写cc++代码混编工程Makefile文件?

    如何编写cc++代码混编工程Makefile文件?
    发表于 03-09 06:55

    嵌入式C语言进阶之道

    之间分工合作,你 要学会模块化编程、要写出规范安全代码、做更合理的优化、减少更多的 bug。所有 的这些,都迫使你必须彻底的理解嵌入
    发表于 04-19 10:15

    MISRA C在安全安全编程中的位置

      由于 C 仍将是 Linux 内核等大型程序的基础语言,我们可以预见两种趋势的共存,以更好地防止 C 程序中的错误,其中 MISRA C 可以发挥作用,并用更安全的语言(如 Rust 和SPARK Ada 用于部分代码
    的头像 发表于 07-01 10:07 669次阅读
    <b class='flag-5'>MISRA</b> C在<b class='flag-5'>安全</b>和<b class='flag-5'>安全</b>编程中的位置