C語言--一個實參與形參賦值引發的思考

首先來看一段代碼:

#include<stdio.h>

void foo(const char **p) {  }

void main(int argc, char **argv) 
{
    foo(argv);

    return ;
}

我們對這段代碼進行編譯,發現它報出了警告:

test.c: In functionmain’:
test.c:14:9: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
     foo(argv);
         ^
test.c:10:6: note: expected ‘const char **’ but argument is of type ‘char **’
 void foo(const char **p) {  }
      ^

一般來說,對程序運行結果沒有影響的警告我們會進行忽略,但是這個程序很短,非常易讀,所以我們並不認爲程序中有引發警告的bug,但是它卻爆出了警告,這就耐人尋味了。

要想了解這個問題,我們需要閱讀ANSI C標準。

如果你對上面的代碼所論述的問題還沒有那麼清楚,請思考如下代碼的運行結果:

#include<stdio.h>

void main(int argc, char **argv) 
{
    char *cp;
    const char *ccp;
    ccp = cp;
    cp = ccp;
}

你覺得兩個賦值語句有什麼不同?emmmm,事實是cp = ccp會爆出警告。

我們來閱讀一下ANSI C的標準吧~

要使上述的賦值形式合法,必須滿足下列條件之一:

  • 兩個操作數都是指向有限定符或無限定符的相容類型的指針。
  • 左邊指針所指向的類型必須具有右邊指針所指向類型的全部限定符。

好了,我們可以對先對第二個代碼進行分析了:

cp是一個指向char類型的指針,無限定符;ccp是一個指向char類型的指針,有限定符。所以當ccp爲左操作數的時候,它含有右邊指針(無)所指向類型的全部限定符。因此沒有警告,反之cp = ccp有警告。

那麼我們來分析一下第一個代碼:

argv是一個指向char*類型的指針,p是指向一個const char*的指針,foo(argv)相當於是執行了p = argv的賦值操作,而它們根本就是不相容的類型,所以也會產生一條診斷信息。

所以對於這種細微的東西,瞭解之後會發現原來是很有趣的一件事情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章