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; /*与规则冲突*/
40.sizeof操作不能作用于具有边缘影响的表达式上(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冲突 */
}
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; /* 与规则冲突 */
}