热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MISRA-C:2004规则常用要点

规则2.1强制汇编语言应该被封装并隔离。在需要使用汇编指令的地方建议以如下方式封装并隔离这些指令(a)汇编函数(b)C函数(c)宏出于效率的考虑有时必须要嵌入一些简单的汇编指令如

规则2.1 强制 汇编语言应该被封装并隔离。
在需要使用汇编指令的地方建议以如下方式封装并隔离这些指令
(a) 汇编函数(b) C 函数(c) 宏
出于效率的考虑有时必须要嵌入一些简单的汇编指令如开关中断
如果不管出于什么原因需要这样做那么最好使用宏来完成
#define NOP asm (“ NOP”);
规则2.2 强制 源代码应该使用 /*…*/ 类型的注释 。
规则2.4 建议 代码段不应被注释掉(comment out)。
当源代码段不需要被编译时,应该使用条件编译来完成(如带有
注释的#if或#ifdef结构)。为这种目的使用注释的开始和结束标记
是危险的,因为C不支持嵌套的注释,而且已经存在于代码段中的任
何注释将影响执行的结果 。
规则5.1 强制 标识符(内部的和外部的)的有效字符不能多于31。
规则6.1 强制 单纯的char类型应该只用做存储和使用字符值 。
规则6.2 强制 signed char和unsigned char类型应该只用做存储
和使用数字值 。
有三种不同的char类型:单纯的char,unsigned char,signed
char。unsigned char和signed char用于数字型数据;char用于字符
型数据。单纯char类型的符号是实现定义的,不应依赖 。
单纯char类型所能接受的操作只有赋值和等于操作符(=、
==、!= )。
规则6.3 建议 应该使用指示了大小和符号的typedef以代替基本
数据类型 。
不应使用基本数值类型char、int、short、long、float和doulbe。
而应使用特定长度(specific-length)的typedef规则。6.3帮助我
们认清存储类型的大小,却不能保证可移植性,这是因为整数提升
(integral promotion的)不对称性。关于整数提升的讨论见节6.10
仍然很重要的是要理解整数大小的实现 。
程序员应该注意这些定义之下的typedef的实际实现 。
比如本文档中建议为所有基本数值类型和字符类型使用如下所示
的ISOPOSIX的typedef。对于32位计算机它们是:
typedef char char_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
typedef float float32_t;
typedef double float64_t;
typedef long double float128_t;

在位域类型的说明中typedef是不必要的。
规则6.4 强制 位域只能被定义为unsigned int或singed int类型。
规则6.5 强制 int类型的位域至少应该为2 bits长度。
1 bit长度的有符号位域是无用的 。
规则7.1 强制 不应使用八进制常量(零除外)和八进制escape序
列 。
规则8.5 强制 头文件中不应有对象或函数的定义。
头文件应该用于声明对象、函数、typedef和宏,而不应该包含或
生成占据存储空间的对象或函数(或它们的片断的定义)。这样就清
晰地划分了只有C文件才包含可执行的源代码,而头文件只能包含声
明 。
规则8.8 强制 外部对象或函数应该声明在唯一的文件中。
规则8.10 强制 在文件范围内声明和定义的所有对象或函数应该具
有内部链接,除非是在需要外部链接的情况下。
如果一个变量只是被同一文件中的函数所使用,那么就用static。
类似地,如果一个函数只是在同一文件中的其他地方调用,那么就用
static。使用static存储类标识符将确保标识符只是在声明它的文件
中是可见的,并且避免了和其他文件或库中的相同标识符发生混淆的
可能性 。
规则9.1 强制 所有自动变量在使用前都应被赋值 。

规则10.5 强制 如果位运算符 ~ 和 <<应用在基本类型为
unsigned char或unsigned short的操作数,结果应
该立即强制转换为操作数的基本类型 。
当这些操作符~和<<用在small integer类型(unsigned char或
unsigned short)时,运算之前要先进行整数提升,结果可能包含并
非预期的高端数据位,例如:
uint8_t port = 0x5aU;
uint8_t result_8;
uint16_t result_16;
uint16_t mode;
result_8 = (~port) >> 4; /* not compliant */
~ port 的值在16 位机器上是0xffa5 , 而在32 位机器上是
0xffffffa5。在每种情况下,result的值是0xfa,然而期望值可能是
0x0a。这样的危险可以通过如下所示的强制转换来避免:
result_8 = ( ( uint8_t ) (~port ) ) >> 4; /* compliant */
result_16 = ( ( uint16_t ) (~(uint16_t) port ) ) >> 4 ; /* compliant */
当<<操作符用在small integer类型时会遇到类似的问题,高端数
据位被保留下来。例如:
result_16 = ( ( port <<4 ) & mode ) >> 6 ; /* not compliant */
result_16的值将依赖于int实现的大小。附加的强制转换可以避
免任何模糊性 。
result_16 = ( ( uint16_t ) ( ( uint16_t ) port <<4 ) & mode ) >> 6 ; /* compliant
*/


规则10.6 强制 后缀“U”应该用在所有unsigned类型的常量上 。
规则12.7 强制 位运算符不能用于基本类型(underlying type)是
有符号的操作数上。
位运算(~、<<、>>、&、^ 和 |) 对有符号整数通常是无意义
的。比如:如果右移运算把符号位移动到数据位上或者左移运算把数
据位移动到符号位上,就会产生问题 。
规则12.9 强制 一元减运算符不能用在基本类型无符号的表达式
上。
规则12.10强制 不要使用逗号运算符。
规则13.5 强制 for语句的三个表达式应该只关注循环控制 。
for语句的三个表达式都给出时它们应该只用于如下目的 :
第一个表达式初始化循环计数器 (例子中的i );
第二个表达式应该包含对循环计数器(i)和其他可选的循环
控制变量的测试 ;
第三个表达式循环计数器(i)的递增或递减 。
规则14.5 强制 不应使用continue语句。
规则16.2 强制 函数不能调用自身不管是直接还是间接的。
规则16.7 建议 函数原型中的指针参数如果不是用于修改所指向的
对象就应该声明为指向const的指针。

本规则会产生更精确的函数接口定义const限定应当用在所指向
的对象而非指针因为要保护的是对象本身。例如:
void myfunc ( int16_t *param1, const int16_t *param2, int16_t *param3 )
/* param1 : Addresses an object which is modified – no const
param2 : Addresses an object which is not modified – const required
param3 : Addresses an object which is not modified – const missing */
{
*param1 = *param2 + *param3;
return;
}
/* data at address param3 has not been changed, but this is not const therefore
not compliant */
规则19.10 强制 在定义函数宏时每个参数实例都应该以小括号括起
来除非它们做为#或##的操作数。
函数宏的定义中参数应该用小括号括起来。例如一个abs函数可以
定义成 :
#define abs (x) ( ( (x) >= 0 ) ? (x) : -(x) )
不能定义成 :
#define abs (x) ( ( (x) >= 0 ) ? x : -x )
如果不坚持本规则,那么当预处理器替代宏进入代码时操作符优
先顺序将不会给出要求的结果。
考虑前面第二个不正确的定义被替代时会发生什么 。
z = abs ( a – b );
将给出如下结果:
z = ( ( a – b >= 0 ) ? a – b : -a – b );

子表达式 – a - b 相当于 (-a)-b而不是希望的 –(a-b)把所有
参数都括进小括号中就可以避免这样的问题 。
规则19.15 强制 应该采取防范措施以避免一个头文件的内容被包含
两次。
规则20.3 强制 传递给库函数的值必须检查其有效性。
规则20.4 强制 不能使用动态堆的内存分配 。
这排除了对函数alloc、malloc、realloc和free的使用。
规则20.5 强制 不要使用错误指示errno 。
规则20.7 强制 不应使用setjmp宏和longjmp函数。
规则20.8 强制 不应使用信号处理工具
规则20.9 强制 在产品代码中不应使用输入/输出库
规则20.10强制 不应使用库中的函数atof、atoi和atol。
当字符串不能被转换时,这些函数具有未定义的行为。
规则20.12强制 不应使用库中的时间处理函数。
规则21.1 强制 最大限度降低运行时错误必须要确保至少使用了下
列方法之一:
a) 静态分析工具/技术;
b) 动态分析工具/技术 ;
c) 显式的代码检测以处理运行时故障 。

 


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
author-avatar
平凡天使007
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有