#include<stdio.h>
int main()
{
return 0;
}
在上面给出的代码片段中,main返回的返回0在哪里?或者换句话说,在开始时称为主函数的函数。
答案 0 :(得分:12)
main
由C运行时库中的某个启动函数调用。 C语言标准表示从main
返回相当于调用exit
函数,因此大多数C运行时看起来像这样:
void _start(void) /* Exact function signature may vary */
{
/* Platform-specifi startup (e.g. fetch argc and argv from the OS) */
...
int status = main(argc, argv);
exit(status);
/* Never reached */
}
退出状态会传递回操作系统,然后从那里发生的操作系统依赖于操作系统。
编译和链接程序时,可执行文件格式(例如PE或ELF)包含一个起始地址,它是执行开始的虚拟地址。该函数通常是C运行时库的一部分(如上面的示例_start
)。该函数必须通过调用exit
之类的系统调用来结束,因为如果它刚刚返回,它将无处可去:它只会从堆栈中弹出一个地址并跳转到该位置,这将是垃圾。
根据OS加载程序初始化进程的方式,程序参数argc
,argv
和其他数据(例如环境)可能作为函数参数(通过寄存器或堆栈)进入),或者他们可能需要系统调用(例如Windows上的GetCommandLine
)来检索它们。但是处理所有这些是C运行时的工作,除非你明确地避免使用C运行库,否则你不必担心这些细节。
答案 1 :(得分:3)
您的编译器针对某个平台,其中包括用于启动进程的特定于操作系统的机制。该平台特定代码的一部分包含main
的返回值。当您将程序链接到可执行文件时,链接器会添加一个特定于操作系统的二进制代码,负责调用main
并将返回值报告回操作系统。
答案 2 :(得分:2)
返回值将转到托管环境。通常,操作系统调用main
并退出程序的退出状态。
答案 3 :(得分:0)
main返回的返回0在哪里?或者换句话说,在开始时称为主函数的函数。
它由C启动库调用,这是一个由内核直接调用的存根函数。例如,在Linux和OS X上,它是一个名为_start
的函数。它与main()
具有相同的签名,操作系统本身使用其返回值。