本文是C編程中一些常見錯誤的總結,有些是顯而易見的,有些則是不容易發現
本文地址:http://www.cnblogs.com/archimedes/p/get-screwed-c.html,轉載請注明源地址。
代碼
a = b; /* 出現bug c = 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)b assign(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,看下面的代碼:
#include <stdio .h> int 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 <stdio.h> #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<u) { /* true!*/ } 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"); // 溢出 }