MISRA C指導指南解讀系列5(MISRA C規則33-45)

2.1.            操作符

33&&||右邊的操作數不應該含有邊緣影響(R

      

       int myfunc1(void);

int myfunc(void)

       {

              int is;

              int x;

              if( is && ( x ++ == 3))     /* 與規則衝突 */

              if( is && (x == myfunc1())) /* 除非myfunc1不會產生邊緣影響 */

}

34&&||的邏輯操作數應該是主要表達式:單一的標識符,常數,或者帶有括號的表達式(R

35.賦值操作不能用在返回布爾值的表達式中(R

void foo()

 {

   int x;

   int y;

   x=y;

   if ( x != 0) {  // Ok

      // ...

   }

   if ( ( x=y) != 0) { /*與規則衝突*/

   }

   if ( x=y ) { /*與規則衝突*/ 

   }

 }

 

36.邏輯操作不能與位循環操作混淆

我們知道,&&||,!是邏輯操作符,而&|~是位操作符號,在邏輯表達式中,不允許使用非邏輯變量,例如:

int a, b;

if(a && b) { /* 與規則36衝突 */

   

}

       37.位操作符不能用在有符號整型(signed int)變量上(R

int goo() {

     return 0;

 }

 

 void foo() {

 

     int dVar = 1;

     signed int sdVar = 0;

     unsigned int udVar = 0u;

 

     udVar = udVar & udVar; /* Ok */   

     udVar = udVar & dVar; /* 與規則37衝突 */   

     udVar = udVar & sdVar; /*與規則37衝突*/   

 

     udVar ^= udVar; /* Ok */   

     udVar ^= dVar; /*與規則37衝突 */   

     udVar ^= sdVar; /*與規則37衝突*/

 

     udVar ^= goo(); /*與規則37衝突*/

 

     unsigned int udVar2 = ~udVar; /* Ok */

     unsigned int udVar3 = ~sdVar; /*與規則37衝突*/

 }

38.移位操作符的右邊的操作數應該介於0和左手邊操作數位長度之間(R)

39.一元負(-)操作符不能作用於無符號的表達式(R

       例如

              unsigned int a;

              int b;

b = -a; /*與規則衝突*/

40sizeof操作不能作用於具有邊緣影響的表達式上(A

void myfunc() {

     int a = 1;  

 

     sizeof(a); /*ok */

     sizeof(a++); /* 與規則衝突 */

 }

41.在確定的編譯器中進行整型相除的時侯,應該是可確定的,文檔化,並進行考慮(A

這是由於在支持ISO C的編譯器中進行除法時可能出現兩種結果,例如,-5/3 有可能是 -1-2,也有可能是商-2+1。因此在使用的時候要指明。

 

       42.逗號運算符(,)不能使用,除非在for循環的控制表達式裏面(R

void foo( int, int );  // Ok

 

 void func() {

     for (int i = 0; i >=0, i < 10; i++) {  // ok

     }

 }

 

 void func_one(int,int,int);  // ok

 void func_two(int,int);      // ok

 

 

 void bar()

 {

   int x,y,z;

 

   func_one( x, y + 2, z );      // ok

   func_two( (x--, y + 2), z );  /*  與規則42衝突 */

 }

2.2.            轉換

43.隱式的轉換可能導致信息的丟失,因此不宜採用(R

void myfunc() {

   signed int a;

   unsigned int b;

 

   a = b; /* 與規則衝突 */

   b = a; /* 與規則衝突 */

 

 }

44.冗餘的顯示轉換不宜使用(A

void myfunc()

 {

     char c = 1;

     short s = 1;

     double d = 1.0;

     

       c = (char ) c; /* 與規則衝突 */

 

       d = (double)(c * s + d); /* 與規則衝突 */

 

     d = (double )(double)1/3; /* 與規則衝突 */

 

     return;

 }

45.指針與任何類型之間的轉換都不要使用(R

{

unsigned long val = 0x00000000;

int *ptr = (int *ptr) val; /* 與規則衝突 */

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章