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这个地址可以变。
#includeint 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#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) { }