我需要維護一些由別人編寫的代碼。我剛剛遇到在一個函數中聲明並在其他地方定義的許多函數。 例如:爲什麼有些人在一個函數內部聲明extern函數?
int func(){
...
extern func1();
extern func2();
...
}
他們爲什麼聲明和定義這樣的功能爲什麼他們不申報的功能之外?有什麼優勢?
我需要維護一些由別人編寫的代碼。我剛剛遇到在一個函數中聲明並在其他地方定義的許多函數。 例如:爲什麼有些人在一個函數內部聲明extern函數?
int func(){
...
extern func1();
extern func2();
...
}
他們爲什麼聲明和定義這樣的功能爲什麼他們不申報的功能之外?有什麼優勢?
這是一個非常危險的做法 - 不能保證原型與實際功能匹配,如果不匹配,各種事情都可能出錯。特別是實際實現這些函數的代碼將不會看到這個聲明,這使得它很危險。
這樣做的正確方法是這兩個函數的作者將他們的聲明放入一個頭文件中,並且使用它們的文件應該包含該頭文件。通常,每個C函數都應該是靜態的,或者應該在頭文件中聲明。
如果代碼是這樣寫的,那是因爲懶惰,並且可能出於爲未來開發人員設置陷阱的願望。您還可以看到聲明使用過時的樣式:extern func1()意味着func1返回一個int(作爲默認值),並且它需要一個未知但固定數量的參數。所以你(和編譯器)甚至不知道如何調用它。
假設功能被實現爲
int func1 (int arg)
和實施者決定了它應改爲
void func1 (int arg, int* result)
通過指針返回一個值,而不是作爲函數結果。奇怪的聲明將確保編譯器沒有機會檢測到這一點,並且在更改後調用func1很可能會崩潰,或者更糟糕的是在應用程序中的某處重寫隨機int。這是一場等待發生的災難。如果您在應用程序中看到類似這樣的代碼,請立即修復它。
張貼的樣品實際上是不正確的原型應該有一個返回類型:
int func(void) {
extern int func1();
return func1();
}
int func2(void) {
return func1(); // declaration out of scope
}
這非常糟糕做法允許func1
的聲明是本地的功能func
身體。功能func
結束後func1
的聲明不起作用。實際上,現代編譯器會跟蹤這種可疑的聲明和抱怨。
這是不好的做法,因爲沒有辦法驗證聲明與實際定義的一致性。將聲明放在包含在使用的文件中以及定義爲的文件中的頭文件中,該函數是正確的方法。
我個人認爲這些聲明是一個壞主意。其他人同意我的看法,因爲海灣合作委員會可以選擇警告他們:'-Wnested-externs'。 – melpomene
我想知道這種做法的優點。@ Maharaj –
爲什麼不呢?你可能不喜歡它,但它是合法的C. – EJP