2017-07-03 132 views
-3

我知道使用沒有原型的函數是錯誤的。 但是當我在擺弄時,我碰到了這個奇怪的衝突的行爲。隱式函數聲明的行爲

TEST1

#include <stdio.h> 
    #include <limits.h> 
    void main(){ 
     char c='\0'; 
     float f=0.0; 
      xof(c,f);/* at this point implicit function declaration is 
generated as int xof(int ,double); */ 
    } 
    int xof(char c,float f) 
    { 
     printf("%d %f\n", c,f); 
    } 

隱函數聲明將是int XOF(INT,雙);

誤差是

variablename.c:8:5: error: conflicting types for 'xof' int xof(char c,float f)

我明白這一點,因爲隱式生成函數聲明(默認整數值爲INT和小數爲DOUBLE哪些)不匹配以下函數定義

TEST2

#include <stdio.h> 


#include <limits.h> 
    void main(){ 
     unsigned int a =UINT_MAX; 
     int b=0; 
     xof(a); /* implicit function declaration should be int xof(int); */ 
    } 

    int xof(unsigned a,int b) 
    { 
     printf("%d %d\n", a,b); 
    } 

隱式函數聲明爲int xof(int);應與函數定義

的衝突,但是這個運行良好(無差錯)和輸出是 與「A」表現爲「INT」值和「B」具有「未定義垃圾」

-1 12260176

有人可以解釋這一點。 在此先感謝。

+1

C在使用前需要正確的聲明。其他任何東西都是無效的C!因此,問「爲什麼這個C代碼做了什麼 - 它不是C代碼,而且你不使用標準的兼容編譯器或忽略警告。根據你的介紹,你很清楚。」 – Olaf

+0

舊版本的C標準允許的函數參數推理,第二個例子可以通過這些鬆散的規則「偷渡」,這是C移動到總是需要前向聲明的原因之一 – AShelly

+0

只需更新一個不超過18年的編譯器,然後你 – Lundin

回答

1

如果在沒有定義的情況下遇到函數調用,則生成的隱式定義將始終爲int (*)(),即接受未指定數量參數並返回int的函數。考慮到函數調用中的實際參數是而不是。那是你誤解的來源。

在第一程序的情況下,所產生的錯誤信息是:因爲實際的函數定義包含一個或多個參數,其類型是受試者爲默認促銷規則出現

/tmp/x1.c:10: error: conflicting types for ‘xof’
/tmp/x1.c:10: note: an argument type that has a default promotion can’t match an empty parameter name list declaration
/tmp/x1.c:6: error: previous implicit declaration of ‘xof’ was here

該錯誤。具體而言,任何低於int(在這種情況下爲char)的整數類型在表達式中被提升爲intfloat參數也是如此,它在表達式中被提升爲double。換句話說,使用隱式聲明將正確類型的參數傳遞給此函數是不可能的。

第二個程序不會生成錯誤,因爲參數(intunsigned int)都不受默認升級規則的約束。在這種情況下,您會調用未定義的行爲,因爲您未傳遞正確類型的正確數量的參數。如果您確實傳入了正確類型的兩個參數,則行爲將會被很好地定義。

請注意,隱式函數聲明是C89特性,並且在C99及更高版本中不受支持,儘管一些編譯器仍然可以在C99或C11模式下將它們接受爲擴展。

+0

謝謝,這清除了我的疑問:) – viru

+0

@MM好的點。更新。 – dbush