C語言:函式宣告與定義的引數不一致問題,後果可能很嚴重哦!!!!!
具體:
在檔案main.c中
int func (); //宣告中沒引數
int main(){
int c = func(); //呼叫時也不傳參,這樣才能編譯通過
printf("%d\n",c);
return 0;
}
在檔案func.c中
int func(int a, int b,int c, int d, int e, int f,int g,int h,int i,int j, int k,int l,int m,int n){
int aa = a;
int bb= b;
int cc =c;
int dd=d;
int ee =e;
int ff=f;
int gg =g;
int hh = h;
int ii = i;
int jj = j;
int kk =k;
int ll =l;
int mm =m;
int nn = n;
a = 0;
b = 0;
d=0;
e = 0;
f = 0;
g = 0;
h = 0;
i = 0;
j = 0;
k = 0;
l = 0;
m = 0;
n = 0;
return b;
}
執行結果
$ gcc main.c func.c
$ ./a.out
0
Segmentation fault
不要懷疑,這個程式可以編譯,連結通過。
但是執行時出錯,因為func的程式碼破壞了main的棧幀,導致“段錯誤”
有人說,C中引數個數有限制,但是畢竟編譯通過了,說明語法沒錯,也就沒有引數個數限制了
這只是個極端的例子,但是還是值得注意:當宣告與定義的引數不一致時,有可能出錯
1)若不定義aa,bb,cc.....這些區域性變數,不把實參a,b,c......傳給他們的話,程式不會出錯
通過比較彙編程式碼,發現:
1)若沒定義int aa = a;.....這些語句,則對實參a,b,c......賦值時,修改的是func()函式的棧幀
2)若有int aa = a;.....這些語句,則對實參a,b,c......賦值時,修改的是main()函式的棧幀 ,這樣當然會把main的棧幀破壞掉