gpt4 book ai didi

c - 为什么 main() 不能在 C 中声明为静态的?

转载 作者:太空狗 更新时间:2023-10-29 16:50:34 29 4
gpt4 key购买 nike

为什么必须将 main 声明为具有外部链接?

为什么它不应该是静态的?

什么是外部链接??

最佳答案

因为您将启动文件链接到您的程序,其中(通常)包含调用 main.c 的汇编代码。如果 main 是静态的,该代码将无法调用 main。

external linkage意味着其他所谓的translation-units可以看到您的符号在其自己的翻译单元中声明为 extern。所以,你的 main 是 extern,它在它的翻译单元符号表中会有一个条目来说明它的地址。当其他翻译单元想要调用 main 时,它们将能够跳转到该地址。

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 中声明为静态的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/320461/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com