2011-11-22 27 views
3

如果單獨編譯「函數」,則不會檢測到不匹配,「函數」將返回一個double,該函數將被視爲一個int ...鑑於我們所說的聲明如何與定義相匹配,這可能會令人驚訝。錯配可能發生的原因是,如果沒有函數原型,函數是隱含在表達它的首次亮相宣佈,如C函數調用:瞭解「隱式int」規則

sum += "the function"(line); 

如果名稱尚未先前聲明發生在一個表達式中,後面跟着一個左括號,它被上下文聲明爲一個函數名,該函數被假定返回一個int,並且沒有任何關於它的參數的假設。

對於模棱兩可的問題,我提前道歉,但這是什麼意思?順便說一下,這是來自Brian W. Kernighan和Dennis M. Ritchie的C Programming Language book第2版的第73頁4.3章。

+0

K&R這是什麼頁面?但我認爲你所問的問題是關於你聲明函數/類型的默認值,它們默認爲「int」。此線程是我認爲你的問題的重複:http://stackoverflow.com/questions/5885156/no-defined-type-of-a-function-parameter-defaults-to-int-am-i-insane – birryree

回答

10

K & R2涵蓋了1989/1990版本的語言。當前的ISO C標準發佈在 2011中,將刪除「隱式int」規則,並且需要對您調用的任何函數進行可視聲明。編譯器不一定默認執行此操作,但您應該能夠請求更嚴格的警告 - 而且您絕對應該這樣做。在寫得很好的新代碼中,規則是不相關的(但有必要理解它)。

一個例子:標準sqrt()功能在<math.h>聲明:

double sqrt(double); 

如果你寫了一個電話沒有所需#include <math.h>

double x = 64.0; 
double y = sqrt(x); 

一個C90編譯器將假設sqrt返回int - 它會生成代碼轉換從intdouble的結果。結果將是垃圾,或者可能是崩潰。

(您可以自己手動聲明sqrt,但這是錯誤的解決方案。)

所以不這樣做。始終包含您呼叫的任何功能所需的任何標題。如果它返回int(並且如果您的編譯器不強制使用嚴格的C99或C11語義,並且滿足其他一些條件),那麼您可能會放棄調用未聲明的函數,但沒有理由這麼做。

瞭解「隱式int」規則對於理解舊代碼或代碼編寫不佳的行爲仍然有用,但是您不應該在新代碼中依賴它。

0

它只是說,如果編譯器遇到調用一個未知的功能代碼,然後它含蓄地對待它,如果它已經看到int unknown();

+0

wrong 。它默認返回int – perreal

+0

你甚至讀過引用的文本嗎? –

+0

@TJD:這是什麼意思,什麼時候有人可能會遇到這個問題?你能提供一個例子嗎? –

7

函數原型引入語言後期形式的聲明原型。

在原型之前,編譯器會假設傳遞給每個未知函數的每個參數都應該作爲整數傳遞,並假定返回值也是一個整數。

這工作得很好了少數情況下,這是正確的,但意味着人們不得不編寫程序在一個尷尬的秩序,使功能絕不會依賴於做匹配這種預期不明的功能。

將原型引入C89(又名ANSI C或ISO C)時,原型允許編譯器準確知道需要什麼類型的參數以及將返回哪些類型的結果。

強烈建議您爲所有新代碼使用函數原型;當在完全舊的代碼庫上工作時,原型可能是有害的。 (或者,如果代碼必須可以在ANSI C編譯器之前編譯,那麼您可能希望忽略原型,以便它可以構建在古老的軟件上。gcc是我在很長時間內看到過的唯一地方)