MISRA C——The Motor Industry Software Reliability Association

内容

修改历史

内容

1        资源

2        MISRA C 2004

2.1        MISRAC introduction

2.2        Rule 8.1 functions shall haveprototype declaration and the prototype shall be visible at both the functiondefinition and call.

2.3        Rule 8.12: When an array is declared with externallinkage, its size shall bestated explicitly or defined implicitly by initialisation.

2.4        Rule10.1 The value of an expression of integer type shall not be implicitlyconverted to a different underlying type if: a) it is not a conversion to awider integer type of the same signedness, or b) the expression is complex, orc) the expression is not constant and is a function argument, or d) theexpression is not constant and is a return expression.

2.4.1        例子

2.5        rule 12.7Bitwise operators shall not be applied to operands whose underlying typeis signed.

2.5.1        例子

2.6        Rule13.6: Numeric variables being used within a for loop for iteration countingshall not be modified in the body of the loop.

2.6.1        例子

2.7        Rule14.2 All non-null statements shall either have at least one side effect howeverexecuted, or cause control flow to change.

2.8        Rule 14.10: All if … else constructsshall be terminated with an else clause.

2.8.1        例子

2.9        Rule 19.4: C macros shall only expandto a braced initialiser, a constant, a string literal, aparenthesisedexpression, a strorage class specifier, or a do-while-zero construct.

2.9.1        例子

2.10     Rule 19.7A function should be used in preference to a function-like macro.

2.10.1      例子

2.11     Rule 19.10: in the definition of a function-like macro each instance of aparameter shall be enclosed in parentheses unless it is used as the operand of# or ##.

2.11.1      例子

2.12     Rule20.2  The names of standard librarymacros, objects and functions shall not be reused. & Rule 1.2:No reliance shall be placed on undefined or unspecified behaviour.

3        MISAR C 2012

 

1       资源

关注激活未来公众号,后台回复“MISAR C 2012”即可免费获取“MISRA C_2012 Guidelines for the useof the C language in critical systems.pdf”文档下载链接,回复“QAC”即可免费获取“QAC-8.1-Win-UsersGuide.pdf”使用手册下载链接。

MISRA官网:https://www.misra.org.uk/

MISRA C_2012 Guidelines for the use of the C language in critical systems.pdf的CSDN下载地址:

https://download.csdn.net/download/Sure_gengjia/12987445

QAC-8.1-Win-UsersGuide.pdf的CSDN下载地址:

https://download.csdn.net/download/Sure_gengjia/12987496

可结合本公众号上一篇文章——MC9S12G128模块化分层化软件架构之八_QAC静态代码分析,在实例中体会MISRA C的规则。

2      MISRA C 2004

2.1     MISRA C introduction

MISRA Mission Statement: To provide assistance to the automotiveindustry in the application and creation within vehicle systems of safe andreliable software.

MISRA, The Motor Industry Software Reliability Association, is a collaboration between vehicle manufacturers, component suppliers andengineering consultancies which seeks to promote best practice in developingsafety-related electronic systems in road vehicles and other embedded systems. Tothis end MISRA publishes documents that provide accessible information forengineers and management, and holds events to permit the exchage of experiencesbetween practitioners.

MISRA使命宣言:为汽车行业中的应用和在车辆系统内创建安全可靠的软件提供帮助。

汽车工业软件可靠性协会(MISRA)是汽车制造商、部件供应商和工程咨询公司之间的合作组织,旨在促进在道路车辆和其他嵌入式系统中开发安全相关电子系统的最佳实现方式。 为此,MISRA出版了一些文件,为工程师和管理层提供了可访问的信息,并举办活动以允许从业人员之间交流经验。

                           

2.2     Rule 8.1functions shall have prototype declaration and the prototype shall be visibleat both the function definition and call.

使用原型可以使编译器检查函数定义和调用的一致性和完整性。如果没有原型,编译器就没有义务承担函数调用中的某些错误(例如,函数主体中的参数数量不同,调用和定义之间的参数类型不匹配)。函数接口是造成大量问题的原因,因此该规则非常重要。

给全局函数实现函数原型的推荐方法是在头文件中声明函数(即给出函数原型),然后将头文件包含在所有需要原型的代码文件中。

2.3     Rule8.12: When an array is declaredwith external linkage, itssize shall be stated explicitly or defined implicitly by initialisation.

当用外部连接声明数组时,其大小应明确声明或通过初始化隐式定义。

int array1[ 10 ];                  /* 符合 */

extern intarray2[];             /* 不符合 */

int array2[ ] = {0, 10, 20};  /* 符合 */

尽管可以声明不完整类型的数组并访问其元素,但是显示地确定数组大小,这样做更安全。

2.4     Rule 10.1 The value of an expression of integer type shall not beimplicitly converted to a different underlying type if: a) it is not aconversion to a wider integer type of the same signedness, or b) the expressionis complex, or c) the expression is not constant and is a function argument, ord) the expression is not constant and is a return expression.

规则10.1 整型表达式的值不能隐式地转化为以下类型:a)不是转化为具有相同符号的更宽泛的整数类型,或者b)表达式很复杂,或者c)表达式不是常数并且是函数参数,或者d)表达式是函数返回表达式,不是常数;

规则10.1大致包括以下原则(principle):

·   有符号和无符号类型之间没有隐式转化;

·   整型和浮点型之间没有隐式转化;

·   宽类型(widertypes)和窄类型(narrower type)之间没有隐式转化;

·   函数参数没有隐式转化;

·   函数返回值没有隐式转化;

·   复杂表达式没有隐式转化;

2.4.1         例子

extern void fool(uint8 x);

 

int16 func1(void)

{

fool( u8a );                           /*符合*/

fool( u8a + u8b );                 /*符合*/

fool( su8a );                         /*不符合*/

fool( u16a );                         /*不符合*/

fool( 2 );                               /*不符合*/

fool( 2U );                            /*符合*/

fool( (uint8)2 )                      /*符合*/

… s8a + u8a…                    /*不符合*/

s8b = u8a;                           /*不符合*/

… u8a + 5…                        /*不符合*/

… u8a + 5U …                     /*符合*/

… u8a + (uint8) 5 …            /*符合*/

u8a = u16a;                         /*不符合*/

u8a = (uint8) u16a;              /*符合*/

u8a = 5UL;                           /*不符合*/

… u8a + 10UL;                     /*符合*/

u8a = 5U;                             /*符合*/

… u8a >> 3                          /*符合*/

… u8a >> 3U                        /*符合*/

… s32a + 80000                   /*符合*/

… s32a + 80000L                 /*符合*/

u8a = u8b + u8c;                   /*符合*/

s16a = u8a + u8n;                 /*不符合*/

s32a = u8b + u8c;                 /*不符合*/

u8a = f32a;                           /*不符合*/

s32a = 1.0;                           /*不符合*/

return s32a;                           /*不符合*/

return 20000;                         /*符合*/

return 20000L;                       /*不符合*/

return s16a;                           /*符合*/

return s8a;                             /*不符合*/

return u16a;                           /*不符合*/

}

2.5     rule 12.7Bitwise operators shall not be applied to operandswhose underlying type is signed.

按位运算符不得应用于其基础类型为带符号的操作数。

按位运算(〜,>,>> =,&,&=,^,^ =,|和| =)通常对有符号整数没有意义。例如,如果右移将符号位移到数字中,或者左移将数字位移到符号位,则会出现问题。

2.5.1         例子

extern S16 test(void)

{

s16a = (S16)(s16a << 2);    /* 不符合 */

s16a = s16a >> 1;               /* 不符合 */

s16a = s16a & 3;                /* 不符合 */

s16a = s16a | 5;                 /* 不符合 */

s16a = (S16)~s16a;           /* 不符合 */

 

u8a = (U8)(u8a << 2);

u8a = u8a >> 1;

u8a = u8a & 0x3U;

u8a = u8a | 0x5U;

u8a = (U8)~u8a;

 

return 1;

}

2.6     Rule 13.6: Numeric variables being used within a for loop foriteration counting shall not be modified in the body of the loop.

在for循环中用于迭代计数的数字变量不得在循环主体中修改。

循环计数器不得在循环主体中修改。但是,可以在循环中修改表示逻辑值的其他循环控制变量,例如,指示已完成某些操作的标志,然后在for语句中对其进行测试。

2.6.1         例子

flag = 1;

for(I = 0; (i < 5) && (flag == 1); i++)

{

flag = 0;           /* 符合,允许提前终止循环 */

i = i + 3;        /* 不符合,改变了循环的计数器 */

}

2.7     Rule 14.2 All non-null statements shall either have at least oneside effect however executed, or cause control flow to change.

所有非null语句无论执行如何,都应当有至少一个side effect,或者对导致控制流改变。

任何无副作用且不会导致控制流改变的语句(空语句除外)通常会指示编程错误,因此,应对此类语句执行静态检查。例如,以下语句在执行时不一定具有副作用:

x >= 3u;          /*不符合,x和3比较,但是比较的结果被丢弃*/

2.8     Rule 14.10: All if … else constructs shall be terminated with an else clause.

所有的if … else 结构都应当以else子句结束。

只要if语句后接一个或多个else if语句,则适用此规则。最后的else后面应带有else语句。对于简单的if语句,则无需包含else语句。

最后的else语句的要求是防御性编程。 else语句应采取适当的措施或包含有关为何不采取任何措施的适当注释。这与在switch语句(15.3)中具有final default子句的要求一致。

2.8.1         例子

简单的if语句:

if ( x < 0 )

{

    x = 0;

}                           /*else not needed*/

if else if 结构:

if ( x < 0 )

{

x = 0;

}

else if ( y < 0 )

{

    x = 3;

}

else                  /*这个else子句是需要的,即使这个else永远到不了*/

{

}

2.9     Rule19.4: C macros shall only expand to a braced initialiser, a constant, a stringliteral, aparenthesised expression, a strorage class specifier, or ado-while-zero construct.

C语言中的宏只能扩展为带括号的初始化程序、常量、字符串字面量、带括号的表达式、存储类说明符或者一个do-while-zero结构。

这些是宏唯一允许的使用。存储类说明符和类型限定符包括诸如extern、static和const之类的关键字。惊醒替换时,#define的任何其他使用都可能导致意外行为,或导致很难度的代码。

特别是,除非是用do-while构造,否则不得使用宏来定义语句或语句的一部分。宏也不应重新定义语言的语法。宏替换列表中所有类型的方括号(){}[]均应保持平衡。

do-while-zero构造(见下面的例子)是在宏主体中具有完整语句的唯一允许的机制。do-while-zero构造用于包装一系列一个或多个语句并确保正确的行为。注意:必须在宏主体的末尾省略分号。

2.9.1         例子

/* 以下都是符合规范的例子*/

#define PI  3.14159F                           /* constant */

#define XSTAL      1000000                /* constant */

#define CLOCK   (XTAL/16)               /* constant expression */

#define PLUS2(X)      ((X) +2)           /* macro expanding toexpression */

#define STOR   extern                        /* storage classspecifier */

#define INIT(value)    {(value),0, 0}    /* braced initializer */

#define CAT (PI)                                 /*parenthesized expression  */

#define FILE_A  “filename.h”              /* string literal */

#define READ_TIME_32() \

do\

{\

    DISABLE_INTERRUPTS(); \

    time_now = ( uint32_t ) TIMER_HI <<16; \

    time_now = time_now | ( uint32_t )TIMER_LO; \

    ENABLE_INTERRUPTS(); \

}while(0)                                                              /* example ofdo-while-zero*/

 

/* 下面的例子不符合规范 */

#define  int32_t long           /* 使用typedef代替 */

#define STARTIF  if(          /* 不平衡()与语言重新定义 */

#define CAT PI                  /* 没有括号的表达式 */

2.10Rule 19.7 A function should be used in preference to a function-likemacro.

应优先使用函数而不是类似函数的宏。

尽管宏可以提供比函数更快的速度,但是函数提供了更安全,更健壮的机制。对于参数的类型检查,以及类函数宏可多次评估参数的问题。

2.10.1       例子

#define MAX( A , B)       (((A)> (B)) ? (A) : (B))       /* MISARviolation */

#define MMAX               ( 14 +32 )                          /* 符合 */

#define                          10                                      /* 符合 */

2.11Rule19.10: in the definitionof a function-like macro each instance of a parameter shall be enclosed inparentheses unless it is used as the operand of # or ##.

在类函数的宏的定义中,参数的每个实例都应该括在括号里,除非其用作#或##的操作数。

2.11.1       例子

#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)。在宏定义中,将所有的参数都放在括号中能避免此类问题。

2.12Rule 20.2  The names ofstandard library macros, objects and functions shall not be reused. &Rule 1.2: No reliance shall be placed on undefined or unspecifiedbehaviour.

标准库的宏、对象和函数的名字不能被重用。

如果程序员使用新版本的标准库宏,对象或函数(例如,增强功能或输入值的检查),则修改后的宏,对象或函数应具有新名称。这是为了避免关于是否正在使用标准宏,对象或函数或是否正在使用该函数的修改版本的混淆。因此,例如,如果编写了新版本的sqrt函数以检查输入是否为负,则该新函数不应命名为“ sqrt”,而应被赋予一个新名称。

3      MISARC2012

行胜于言

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值