簡體   English   中英

為什么main()不能在C中聲明為靜態?

[英]Why main() cannot be declared as a static in C?

為什么main必須被聲明為具有外部鏈接?

為什么它不應該是靜態的?

什么是外部聯系?

因為您將啟動文件鏈接到您的程序,該程序包含(通常)調用main的匯編程序代碼。 如果main是靜態的,那么該代碼將無法調用main。

external linkage意味着其他所謂的translation-units可以在自己的翻譯translation-units中看到您的符號被聲明為extern。 所以,你的主要是extern,它的翻譯單元符號表中會有一個表示其地址的條目。 其他翻譯單元將能夠在他們想要呼叫主要時跳轉到該地址。

static linkage意味着您的符號是嚴格的翻譯單位本地。 這意味着其他translation units將無法看到該符號。 因此,具有靜態鏈接的符號可以多次出現在不同的翻譯單元中,並且它們不會彼此沖突,因為它們是本地的。

編輯 :通常,編譯器從翻譯單元生成的文件特定於該特定編譯器。 對於linux上的gcc,通常使用ELF對象格式。 您可以使用readelf -sW <file>.o查看其符號表(下面的簡單測試文件):

test.c的

void bar(void);

static int foo(void) {
    return 1;
}

int main(void) {
    bar();
    return foo();
}

這是readelf的輸出:

Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000    10 FUNC    LOCAL  DEFAULT    1 foo
     6: 00000000     0 SECTION LOCAL  DEFAULT    6
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 0000000a    36 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar

您可以看到main函數和main調用的靜態foo函數。 還有一個函數被調用,該函數未在文件中定義,但在另一個目標文件中定義。 由於目標文件尚未最終鏈接,因此這些函數尚未分配最終地址。 在最終鏈接之后,這些將被安排到可執行文件中並將分配地址。 目標文件具有用於調用尚未定義的函數的條目,因此在鏈接文件時,這些調用指令可以存儲最終地址( readelf -r <file>.o ):

Relocation section '.rel.text' at offset 0x308 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001c  00000902 R_386_PC32        00000000   bar

代碼的真正起點隱藏在C運行時庫中。 此運行時庫調用main()例程。 為了讓鏈接器將C RTL調用與main()函數連接,它需要在文件外部可見。

外部鏈接就是這樣:它意味着有問題的名稱作為目標文件導出的一部分可見。 鏈接器的工作是連接所有導入和導出,以便沒有未完成的導入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM