2016-06-14 58 views
-2

主要問題是:C編譯器如何處理不同源代碼中main函數的多個定義? 像:C編譯器如何處理不同的主函數定義?

無效的主要(無效)

INT主要(無效)

INT主(INT ARGC,CHAR *的argv []) ...

我不知道如果這與名稱修飾有關,那只有當C代碼與C++代碼鏈接而不使用extern「C」時纔會發生,但我只是通過Linux程序員手冊(shell上的普通人命令)查詢功能打開(man 2打開)並顯示兩個簽名:

OPEN(2)的Linux程序員手冊

NAME

open, creat - open and possibly create a file or device 

提要

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 

    int open(const char *pathname, int flags); 
    int open(const char *pathname, int flags, mode_t mode); 

    int creat(const char *pathname, mode_t mode); 

這可怎麼工作的?它的處理就像主函數的定義一樣?

+1

我想知道你的意思是不同類型的多重聲明或多重定義。如果你給出了你的行爲不清楚的示例代碼(你自己的程序),這將有所幫助。目前還不清楚這個問題與[linux]和[C++]有什麼關係。 – PJTraill

+1

名稱修飾不會發生在C名稱上,而是C++名稱超載,以適應鏈接器的限制。因此,它與C編譯器(也可能是鏈接器)在你的程序中的作用沒有任何關係。 – PJTraill

+0

這不是有效的C代碼。 C和C++是**不同的**語言!即使相同的語法/語法也可以具有不同的語義。 – Olaf

回答

2

無論如何它喜歡。如果您未以標準禁止的兩種方式之一聲明main,或者您以兩種的方式聲明它,則編譯器可以將您的汽車傳送到月球,如果它想。進一步的合理化是毫無意義的。

[C99: 5.1.2.2.1/1]:[..]它應具有的int返回類型和不帶參數進行定義:[..]具有兩個參數[..]

[C99: 5.1.2.2.1/2]:如果聲明它們,則主函數的參數應服從以下約束條件:[..]

[C99: 3.4.3/1]:未定義行爲
行爲,在使用非便攜式或錯誤的程序結構的或錯誤的數據,對於這本國際標準並沒有規定要求

4

open實際上並不具有過載或多個聲明。它被宣佈爲open(const char *pathname, int flags, ...),第三個參數被讀取爲va_arg,並且當flags包括O_CREAT時被解釋爲mode_t

如果您有多個main的定義或者具有相同C名稱的多個符號,那麼您可能會遇到鏈接器錯誤。

+0

謝謝zneak,很好的回答 – joaopauloribeiro

+0

我想我誤解了,關於主要的問題不是關於在同一個源代碼中有兩個或多個定義,而是編譯器如何處理不同代碼中的不同定義,就像我可以做的那樣void main(void)或int main(void)... – joaopauloribeiro

+1

@joaopauloribeiro,編譯器負責確保'main'被C運行時正確調用。它被調用的方式必須考慮到它可能有也可能沒有參數,可能會或可能不會返回一個值(在'main'被允許返回'void'作爲C標準的擴展的平臺上)。它可以被視爲一種特殊情況;你不一定會得到這種寬容與其他功能。 – zneak

3

C編程語言的典型實現可以容忍調用者將太多參數傳遞給函數。在類Unix系統中,當啓動代碼調用到main,它通過三個參數,就好像main被宣佈爲

int main(int argc, char *argv[], char *environ[]); 

,其中第三個參數是環境。如果main定義的參數少於這個參數,那麼與典型的調用約定一樣,所有東西仍然可以正常工作,額外的參數放置方式不會受到影響(例如,在第一個參數之上的堆棧或額外的寄存器中) 。

歷史上,open函數的工作原理類似:open被聲明爲沒有原型,所以編譯器無法檢查您傳遞了多少個參數。 open的定義期望三個參數,如果你只傳遞了兩個參數,open將爲第三個參數獲取堆棧上的所有內容,這並不重要,因爲當調用open而不是O_CREAT時,第三個參數不會影響結果。

+0

因此,如果打開的函數抓取堆棧中的「whatever」,它可能會打破其他函數的堆棧? – joaopauloribeiro

+1

與生活中的一切 - 你可以抓住少於你的份額,但嘗試採取更多,並承受後果。 – SergeyA

+1

@joaopauloribeiro由於它不會覆蓋它的參數,並且'open'永遠不會是頂層棧幀,所以這不是問題。 – fuz