zoukankan      html  css  js  c++  java
  • 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] = ''

    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
    ", 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
    ", sizeof(status1));
       printf( "Memory size occupied by status2 : %d
    ", 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)
    {
    }
     
  • 相关阅读:
    .Net并行编程
    ShopEx4.8.5.55328破解版
    PLinq
    C# 4.0 Parallel
    WCF、Web API、WCF REST、Web Service
    WCF 采用net.tcp协议
    MVC 过滤器3
    go orcale
    获取合并单元格中值的一个方法POI
    发起、维持和发展以利润为导向的企业的有目的性的行为(转)
  • 原文地址:https://www.cnblogs.com/focus-z/p/11456302.html
Copyright © 2011-2022 走看看