The Motor Industry Software Reliability Association
MISRA-C-:2004 Guidelines
for the use
of the
C language
in critical systems 中文版
1背景 —— C的使用和问题 (3)
1.1汽车工业中C的使用 (3)
1.2语言的不安全性和C语言 (3)
1.3安全相关系统中C的使用 (4)
1.4标准化 (5)
2MISRA-C:视野 (6)
2.1MISRA-C的发布说明 (6)
2.2MISRA-C的目标 (6)
3MISRA-C:范围 (7)
3.1基本的语言问题 (7)
3.2未指出的问题 (7)
3.3可应用性 (7)
3.4预备知识 (7)
3.5C++问题 (7)
3.6自动产生代码的问题 (8)
4使用MISRA-C (9)
4.1软件工程环境 (9)
4.2编程语言和编码环境 (9)
4.3采用子集(subset) (11)
4.4符合性声明(Claiming compliance) (13)
4.5持续改进 (13)
5规则简介 (14)
5.1规则分类 (14)
5.2规则的组织 (14)
5.3规则的冗余 (14)
5.4规则的形式 (14)
5.5理解原始参考 (15)
5.6规则的范围 (17)
6规则 (18)
6.1环境 (18)
6.2语言扩展 (19)
6.3文档 (19)
6.4字符集 (21)
6.5标识符 (21)
6.6类型 (23)
6.7常量 (24)
6.8声明与定义 (25)
6.9初始化 (27)
c语言中文网汇编语言6.10数值类型转换 (27)
6.11指针类型转换 (36)
6.12表达式 (37)
6.13控制语句表达式 (43)
6.14控制流 (45)
6.15switch语句 (48)
6.16函数 (50)
6.17指针和数组 (51)
6.18结构与联合 (54)
6.19预处理指令 (57)
6.20标准库 (62)
6.21运行时错误 (64)
7References (66)
Appendix A: Summary of rules (68)
Appendix B:MISRA-C :1998 到 MISRA-C :2004 规则映射 (74)
Appendix C:MISRA-C:1998 – 已废除的规则 (81)
Appendix D:ISO标准交互参考 (82)
Appendix E : 术语表 (85)
1背景——C的使用和问题
1.1 汽车工业中C的使用
MISRA-C:1998 [1] 发布于1998年。本文档是它的修订版本,用来解决与第一版本有关系的问题。
在汽车工业领域的实时嵌入式应用中,C编程语言的使用越来越体现出广泛性和重要性。这在相当程
度上取决于该语言固有的灵活性、可支持的范围及其潜在的访问广泛硬件环境的可移植性。详细的理由包括:
z对于许多使用中的微处理器来说,如果存在其他除了汇编语言之外的可用语言,通常就是C。在许多情况下,其他语言根本就不可用于硬件。
z C对高速、底层、输入/输出操作等提供了很好的支持,而这些特性是许多汽车嵌入式系统的基本特性。
z由于应用的逐步增长的复杂性,高级语言的使用较汇编语言更为适合。
z相对于其他一些高级语言,C能够产生较小的和较少RAM密集性(RAM-intensive)的代码。
z增长的可移植性需求。市场竞争要求在工程项目生命周期的任何阶段,软件可以通过移植到新的和/或低成本的处理器,目的是为了降低硬件成本。
z增长的自动产生C代码的使用要求。C代码需要从模型包中自动产生。
z增长的对开放系统和主机环境(hosted enviroments)的兴趣。
1.2 语言的不安全性和C语言
没有哪种编程语言能够保证最终的可执行代码会准确地按照程序员预想的那样执行。任何语言都会产生大量的问题,下面为其做了广泛的分类,并描述了C语言不安全性的例子。
1.2.1程序员产生错误
程序员产生的错误,简单的可以是变量名字的书写错误,或者更为复杂的错误,如对算法的误解。编程语言可以承受这样的错误。首先,语言的风格和表达能帮助或提示程序员清晰考虑其算法。其次,对于书写错误,语言可以使从一个有效结构向另一个有效(不是预想的)结构的转换变得轻松或困难。第三,当错误发生时,语言可以检测到也可能检测不到。
首先,关于语言的风格和表达,使用C可以编写出良好布局的、结构化的和表达性强的代码。还可以使用它编写出不正当的和特别难以理解的代码。很明显,后者对于安全相关的系统是不可接受的。
其次,C的语法特性足以使得书写错误也能产生完全有效的代码。例如,在“==”(逻辑比较)的地方写成“=”(赋值)是很常见的,而且最终结果也几乎总是有效的(但它是错误的);而if语句的结尾出现的多余分号能完全改变代码逻辑。
第三,C的基本观点是假设程序员知道他们在做什么,这意味着错误即使出现也不会被语言注意到而通过。在这方面C体现出的软弱性正在于它的“书写检查”(type checking)。举例来说,C不会拒绝程
序员在使用整数代表true/false值时却在该整数中存储了浮点值。大多数这样的失配可以简单地通过强制使其合适。如果C的表现不得其所(a square peg and a round),
它不会挑剔而会适合它们!
1.2.2程序员不了解语言
程序员可能会误解语言构造的作用。对这样的误解,一些语言是更为开放的。
C语言中有相当多的地方能使程序员轻易产生误解。例如运算符优先级的规则。这些规则是良好定义的,但也非常复杂,也很容易对某特定表达式中运算符的优先级做出错误的假设。
1.2.3编译器的行为同程序员预期的不同
如果语言具有未经完善定义的特性,或者模糊特性,那么在程序员认为某个构造应该如此时,编译器的解释却是完全不同的。
C语言中许多地方是未经完善定义的,因此其行为可能会随着编译器的改变而改变。某些情况下,其行为甚至在同一个编译器内也会根据上下文而发生变化。Annex G中所有的C标准列出了201个这种问题。这可以提出相当多的问题,特别是在面临编译器间的移植性时。然而,C标准 [2] 列出了这些问题,所以它们能为我们所知。
1.2.4编译器包含错误
语言的编译器(及其链接器等)本身就是软件工具。编译器可能不会始终正确地编译代码。例如,在特定环境下它们可能同语言标准相违背,或者其本身可能就包含“bug”。
因为C语言中存在许多难以理解的地方,编译器的编写者很容易错误地解释和实现标准。语言的某些地方比其他的更容易这样。而且编译器的编写者有时会有意改变标准。
1.2.5运行时错误
有些不同的语言问题产生自正确编译的代码,但某些特殊数据会在代码运行时产生错误。语言能够对可执行代码内部做运行时的检查以检测这样的错误并执行适当的动作。
通常,C的运行时检查能力比较弱。这也是C代码短小有效的原因之一,但是在运行中检查错误就要花费一定的代价。C编译器通常不为某些常见问题提供运行时检查,诸如数学异常(如零除)、溢出、指针地址的有效性,或数组越界错误。
1.3 安全相关系统中C的使用
从1.2节可以清楚地知道,在安全相关系统中使用C语言需要相当小心。针对上面提及的问题种类,已
经为安全相关系统中C的使用提出了许多需要关注的事情。显然地,不能为安全相关系统使用所有的C语言特性。
然而,做为语言来说,C是非常成熟的,在实践中也是经过了良好分析和使用的。所以它的不足也是众所周知和可以理解的。同时可获得大量的商业工具支持,这些工具用来静态检查C源代码和提醒程序员语言问题的存在。
如果为了实践的原因有必要在安全相关系统中使用C语言,那么必须对语言的使用加以限制,避免那些确实可以产生问题的地方,直到它是可以应用的。本文档为人们提供了这样的限制集合(通常称为“语言子集”(language subset))。
Hatton [3] 认为,倘若强加了“……严格和自动的强制性约束……”,那么C能够写出“……至少同其他通用语言一样的具有高质量和一致性的软件”。
注意,相对于C语言,汇编语言不再适合于安全相关系统,在某些方面还会更坏。通常不建议在安全相关系统中使用汇编语言,即使使用也要加以非常严格的约束。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论