MISRA C:2012 8 Rules 8.1 A Standard C environment


8.1 

程序不得違反標准C語法和約束,不得超出實現的轉換限制

0232  十六進制轉義序列的值在“unsigned char”類型中無法表示。

int ia = '\x4142';                    /* Message 0232 */

char 字符常量只有1個Byte大小(不考慮寬字符常量),‘\x4142’ = 16706, 超過范圍了。 0-255

十六進制轉義序列的值不得超過unsigned char中可表示的值的范圍.

char 類型用於存儲字母和標點符號之類的字符,但是在技術實現上char卻是整數類型,這是因為char類型實際存儲的是整數而不是字符

char grade  = 'A' ;

char grade = 65; // 這是一種不好的編程風格

令人奇怪的是,C將字符常量視為int類型而非char類型

 0233 八進制轉義序列的值不得超過unsigned char中可表示的值的范圍

/*PRQA S 3123,3211,3408,3610,3625,3628 ++*/

int ia = '\432';                    /* Message 0233 */

0322 'for'語句聲明中使用的非法存儲類說明符

for循環的第一項可以聲明變量,但是只有'auto' and 'register'兩個存儲類說明符可以用, 'static', 'extern' or 'typedef'不可用

void foo(void)
{
    for (static int i = 0; i < 10; ++i)    /* Message 0322 */
    {
    }
}

https://blog.csdn.net/wfreehorse/article/details/60762579

 0338 八進制和16進制轉義字符值超過‘unsigned char’ ‘wchar_t’所表示的范圍

char *s = "\400";                    /* Message 0338 */
// \400 = 256  ; \377 = 255 
// "\400" 是一個字符數組,s[0] = '\400' , s[1] = '\0'

0422 調用函數是傳參的個數 小於 函數原型指定的參數個數

int foo(int a, int b);

void test(int x)
{
    int ret;

    ret = foo(x);              /* Message 0422 */
}

0423 調用函數是傳參的個數 大於 函數原型指定的參數個數

0426 被調用函數返回類型不完整

typedef struct S T1;

extern T1 s;
extern T1 foo1(int n);

void foo2(int n)
{ /* struct S 還沒定義 */
    s = foo1(n);                /* Message 0426                     */
}

struct S {int a; int b;};       /* struct S is now a complete type  */

void foo3(int n)
{
    s = foo1(n);                /* OK - return type is now complete */
}

0427 該對象已被用作函數或函數指針標識符。

void foo(void)
{
    int r;
    int name;

    r = name();                 /* Message 0427 */
}

0429 一個函數的參數是算術類型,但是傳進去的參數不是算術類型。

extern void foo(int p);

struct ST1 { int si; char sbuf[10];};
union  UN1 { int ui; int uj;};

extern struct ST1 st1a;
extern union  UN1 un1a;

extern int *pi;
extern int gi;


extern void test(void)
{
    foo(gi);                  /* OK           */
    foo(pi);                  /* Message 0429 */
    foo(&gi);                 /* Message 0429 */
    foo(st1a);                /* Message 0429 */
    foo(un1a);                /* Message 0429 */
}

0430 跟上一條類似,函數傳參類型不匹配。

0431 函數參數指向受限類型(Function argument points to a more heavily qualified type)。

不能把const type *  傳給函數參數原型為  type*  

不能把volatile type *  傳給函數參數原型為  type*  

反之可以,可以把 type *  傳給函數參數原型為 const  type*  

eg:

const int *a;

int *b;

b = a; // wrong

a = b; // right 指針a指向的內容不能變(不能通過指針a改變,可以通過其他指針改變),但是指針a這個地址可以變。

#include<stdio.h>

int main()
{
    const int a[3] = { 1 , 2,3 };
    const int *c = a;
    int b[3] = { 4,5,6 };
    //a = b;
    c = b;
    //c[1] = 3; // wrong
    //b = c;// wrong
    printf("%d\n", c[1]);
}

 

extern void fi(int * pi);
extern void fci(const int * pci);
extern void fvi(volatile int * pvi);
extern void fcvi(const volatile int * pcvi);

extern int *pi;
extern const int *pci;
extern volatile int *pvi;
extern const volatile int *pcvi;


void test(void)
{
    fi(pi);                   /*              */
    fi(pci);                  /* Message 0431 */
    fi(pvi);                  /* Message 0431 */
    fi(pcvi);                 /* Message 0431 */

    fci(pi);                  /*              */
    fci(pci);                 /*              */
    fci(pvi);                 /* Message 0431 */
    fci(pcvi);                /* Message 0431 */

    fvi(pi);                  /*              */
    fvi(pci);                 /* Message 0431 */
    fvi(pvi);                 /*              */
    fvi(pcvi);                /* Message 0431 */

    fcvi(pi);                 /*              */
    fcvi(pci);                /*              */
    fcvi(pvi);                /*              */
    fcvi(pcvi);               /*              */
}

 0432 函數參數不是兼容的指針類型

struct ST1 { int si; char sbuf[10];};
union  UN1 { int ui; int uj;};

extern struct ST1 st1a;
extern union  UN1 un1a;

extern char *pc;
extern char **ppc;
extern char gc;
extern char cbuf[10];
extern unsigned char *puc;

extern void foo(char * ptp);

void test(void)
{
    foo(pc);                  /* OK           */
    foo(st1a);                /* Message 0432 */
    foo(un1a);                /* Message 0432 */
    foo(gc);                  /* Message 0432 */
    foo(ppc);                 /* Message 0432 */
    foo(cbuf);                /* OK           */
    foo(puc);   /* Message 0432   'char' and 'unsigned char' (or 'signed char') are distinct types*/
}

0446 ++ / -- 操作數必須是標量

struct ST  {int a; int b;};
union  UN  {char c[4]; int x;};

extern struct ST st;
extern union  UN un;

void foo(void)
{
    st++;                       /* Message 0446 */
    un++;                       /* Message 0446 */
}

0447 ++ /  -- 的操作數必須是可修改的對象。

extern        int x[10];
extern const  int y;

void foo(void)
{
    ++x;                        /* Message 0447 */
    ++y;                        /* Message 0447 */
}

0448 ++ /  -- 的操作數不能是指向未知大小的對象的指針。

extern struct TAG *pc;
extern int (*pa)[];
extern void       *pv;

void foo (void)
{
    ++pc;               /* Message 0448 */
    ++pv;               /* Message 0448 */
    ++pa;               /* Message 0448 */
}

0449 ++ /  -- 的操作數不能是函數指針

extern void (*fn_ptr)(void);

void foo (void)
{
   ++fn_ptr;                  /* Message 0449 */
}

0450 數組類型表達式不能 類型轉換

類型轉換的操作數必須是標量類型(scalar type)  (A basic type, enumeration type or pointer type)

(The type char, the signed and unsigned integer types, and the floating types)

struct ST { int ai[3]; };

extern struct ST sf(void);
extern struct ST sta;
extern int       ibuf[10];

void foo(void)
{
    char *pc;

    pc = (char *)ibuf;              /* OK - ibuf decays to type pointer to int      */
    pc = (char *)(sta.ai);          /* OK - sta.ai decays to type pointer to int    */ pc = (char *)(sf().ai);         /* Message 0450 and also 0481 */
    pc = (char *)sta;               /* Message 0481 - sta is not of scalar type     */
}

0452 指針下標索引未知大小的對象。

extern struct ST *gx;           /* The size of struct ST is unknown */

void foo(struct ST *px)
{
   *gx = px[2];                 /* Message 0452 */
}

0454  取地址符& 不能應用於 使用'register'聲明的對象

void foo (void)
{
    register int a;
    int *pa;

    pa = &a;               /* Message 0454 */
}

The address-of operator '&' cannot be applied to an object declared with the 'register' storage-class specifier.

The C language defines five storage-class specifiers: static, extern, auto, register and typedef

0456 該表達式沒有地址 - “&”只能應用於左值或函數指示符。

運算符&只能應用於函數指示符或左值,不能指定 位字段 且不能 指定 寄存器存儲類說明符 聲明的對象。

extern int g;
extern void func(int x);

void foo(void)
{
    int *pi;
    void (*pvf)(int x);

    pi = &g;           /* Operand of & is an lvalue              */
    pvf = &func;       /* Operand of & is a function designator  */
    pvf = func;        /* & is optional on a function designator */ /* See ISO-C90 6.2.2.1 */

    pi = &(g + 1);     /* Message 0456                           */
}

0457 取地址符不能應用在位字段

位bit 可以占據 一個字節byte中的部分或者全部, & 根據字節讀地址,不能精確到字節中某一位的地址。

struct flags {
   unsigned int hi:1;
   unsigned int lo:1;
   unsigned int ins:1;
   unsigned int ovr:1;
};

int main(void)
{
   struct flags f;
   int *ip;
   unsigned int i;

   f.hi = 0;
   f.lo = 0;
   f.ins = 0;
   f.ovr = 0;


   ip = &(f.hi);           /* Message 0457 */
   ip = &f.lo;             /* Message 0457 */

   i = f.ins;

   return 0;
}

https://blog.csdn.net/huasir_hit/article/details/75201126

有些信息在存儲時,並不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,並使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位划分為幾個不同的區域,並說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾 
個不同的對象用一個字節的二進制位域來表示。 

一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為: 
  struct 位域結構名 
  { 位域列表 }; 
  其中位域列表的形式為: 類型說明符 位域名:位域長度 

 https://www.runoob.com/cprogramming/c-bit-fields.html.

#include <stdio.h>
#include <string.h>
 
/* 定義簡單的結構 */
struct
{
  unsigned int widthValidated;
  unsigned int heightValidated;
} status1;
 
/* 定義位域結構 */
struct
{
  unsigned int widthValidated : 1;
  unsigned int heightValidated : 1;
} status2;
 
int main( )
{
   printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
   printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
 
   return 0;
}
/*當上面的代碼被編譯和執行時,它會產生下列結果:*/
Memory size occupied by status1 : 8
Memory size occupied by status2 : 4
/* 位域聲明
在結構內聲明位域的形式如下:
*/
struct
{
  type [member_name] : width ;
};
0457 取地址符不能應用在位字段

0482 Expressions may only be cast to 'void' or scalar types.

typedef struct ST { int a; } T;
typedef void (FUNC)(void);

int bar(void);

void foo(int n)
{
    T  t;

    t = (T)n;         /* Message 0482 - attempting to cast to struct type   */
    (FUNC)n;          /* Message 0482 - attempting to cast to function type */
    (void)bar();      /* OK                                                 */
}

0483 指向未知大小的對象的指針不能是加法運算符的操作數。

當進行任何一種指針的算術運算時,必須要知道指針指向對象的大小,例如,指針 加1,指針的值不是增加1,增加的是指向對象類型的大小。

extern struct ST *ps;
extern void *pv;

void foo(int n)
{
   ps = ps + n;       /* Message 483 */
   pv = pv + n;       /* Message 483 */
}

0546 枚舉類型定義不完整

enum ETAG ex;                       /* Message 0546 */

void foo(void)
{
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM