本文共 2753 字,大约阅读时间需要 9 分钟。
本文是C编程中一些常见错误的总结,有些是显而易见的,有些则是不容易发现
本文地址:,转载请注明源地址。
代码
a = b; /* 出现bugc = d; /* c = d将不会执行*/
代码:
if(a = b) c; /*a恒等于b,只有当b!=0的时候才执行*/
再看下面的代码:
if(0 < a < 5) c; /*布尔表达式恒为真*/
上面代码中的bool表达式恒为真,由于0 < a的值为0或1,永远都小于5成立,当然C中没有bool表达式,这里只是假设
代码:
#define assign(a,b) a=(char)bassign(x,y>>8)
变成
x=(char)y>>8 /* 可能不是你的目的 */
代码:
//foo.h:struct foo { BOOL a};//F1.c#define BOOL char#include "foo.h"//F2.c#define BOOL int#include "foo.h"
F1与F2对结构体foo中的BOOL类型定义不一致,如果交互就会出现错误
可能你会写下面的代码:
int foo (a){ if (a) return(1); } /* bug,因为有时候没有值返回 */
看下面的比特包结构:
struct eeh_type{ uint16 size: 10; /* 10 bits */ uint16 code: 6; /* 6 bits */};
取决于用哪个C编译器,还有你的机器使用大小端,这段代码实现为:
<10-bits><6-bits> 或 <6-bits><10-bits>
同时取决于C编译器、机器体系结构、不可思议的优先设置,这些项可能对齐到最近的8, 16, 32, or 64 bits.
foo(pointer->member, pointer = &buffer[0]);
不同的编译器针对函数参数有不同的求值顺序,gcc是从左到右的求值顺序,有的编译器是从右往左
代码:
if( ... ) foo(); else bar();
当加上调试输出信息:
if( ... ) foo(); else printf( "Calling bar()" ); /* 注意! else止于此 */ bar(); /* 注意! bar永远会被执行 */
代码:
char *f() { char result[80]; sprintf(result,"anything will do"); return(result); /* 注意! result 被分配在栈上. */ }int g() { char *p; p = f(); printf("f() returns: %s\n",p); }
哪怕一个简单的表达式,C没有定义副作用的顺序,结果取决于你的编译器,i/i++可能等于0或1,看下面的代码:
#includeint foo(int n) {printf("Foo got %d\n", n); return(0);}int bar(int n) {printf("Bar got %d\n", n); return(0);}int main(int argc, char *argv[]) { int m = 0; int (*(fun_array[3]))(); int i = 1; int ii = i/++i; printf("i/++i = %d, ",ii); fun_array[1] = foo; fun_array[2] = bar; (fun_array[++m])(++m); return 0;}
事实上这个bug不是那么出名,但是一旦发生严重性不会输给其他的bug,看下面的代码:
void foo(a){ int b; if(b) { /* bug! b没有被初始化 */ }}
现代编译器会发出错误的警告,看下面代码:
void foo(int a) { BYTE *B; if(a) B=Malloc(a); if(B) { /* BUG! B 可能没被初始化 */ *b=a; } }
编译时环境产生成百上千的编译信息,我们对此知之甚少。有些危险的常用名,导致很难被发现:
#include#define BUFFSIZE 2048 long foo[BUFSIZ]; //注意拼写: BUFSIZ != BUFFSIZE
编译器不会报错,因为BUFSIZ已经在stdio.h中定义
在C中,八进制数以0开始,如果数字中没有‘8’或‘9’出现,编译器不会警告
int numbers[] = { 001, 010, // 8 而不是 10 014 }; // 12, 而不是 14
C中的有符号char可能出现各种错误,比如128是一个负数,另外,任何使用低精度整数都必须十分的小心,C使得这些太容易被忽略了
char s = 127;unsigned char u = 127;s++; /* 结果是负数 */if (s 127) { /* 永不可能为true */ }if(u<0) { /* 永不可能为true*/ }
代码:
{ int a=1,b=2; char buf[10]; scanf("%d %d",a,b); // &a,&b? sprintf(buf,"this is the result: %d %d"); // 溢出 }