运行时异常发生后,main()函数返回什么?

3

当程序遇到运行时异常(例如分段错误)时,C语言中的int main()函数返回什么?

在寻找答案时,我遇到了许多关于main()应该返回什么的讨论/帖子,比如这个链接


1
相关(如果不是重复):一个发生段错误的进程会返回什么错误代码? - Martin R
你在问什么平台?Linux吗?你能添加相关的标签吗? - Sander De Dycker
@SanderDeDycker 不针对特定平台。 - meaning-matters
@meaning-matters:那么这个问题是无法回答的:硬件异常不在C标准范围内。 - Sander De Dycker
@SanderDeDycker C标准对访问空指针、除零等情况没有明确规定吗? - meaning-matters
@meaning-matters:C标准将解引用空指针除以零(以及其他类似的硬件异常)称为未定义行为,即不受C标准覆盖。 - Sander De Dycker
2个回答

9

main函数如果程序崩溃就不会返回结果。如果程序崩溃,那么操作系统会杀死程序,因此程序已经不再运行,包括main函数在内。无法运行的程序没有返回值。返回给运行环境的内容取决于接管程序后的操作系统。

操作系统处理返回值。对于 POSIX 系统,被信号(如SIGSEGV,分段错误)杀死的进程,操作系统将返回128加上信号编号。例如在这个waitpid参考页面(及其链接)中有相关文档。

对于 Windows,通常以一个加了其他标志和数据的神秘长整型数值(通常是值0x80000000)报告。

对于旧版或更原始的操作系统,它们不能处理崩溃,因此“返回”的值通常是在崩溃时在“返回值”寄存器或堆栈顶部处的内容。


当然可以,但是会传递什么值到系统中(在某些平台上可以在shell中捕获)呢? - meaning-matters
1
wait函数的状态表明进程是由于信号而死亡,以及是哪个信号。请查看wait()waitpid()或任何其他替代方案的手册页。 - Jonathan Leffler
@meaning-matters 在谈到 shell 时,如果一个进程因为信号终止,POSIX 规定 $? 的值将会是大于 128 的数字。Bash 使用的是 128 加上信号的编号;其他的 Shell 也可能会这么做。 - Shawn
@Someprogrammerdude,你应该把你最后的评论移到答案中。那才是OP真正想知道的。 - klutt
我觉得这个答案更适合回答一个像“程序崩溃时会发生什么”的问题。原始问题“运行时异常时main返回什么”仍然存在(在我看来),被这个答案的扩展编辑所预示,它针对的是在给定操作系统中正在发生的事情(我认为这是一个不同的问题)。此外,第一句话是不正确的。main确实会返回一些东西。 - Joel
1
@Joel 如果程序崩溃了,它就不能再运行了。这包括 main 函数,如果它没有运行,就根本无法返回任何东西。 - Some programmer dude

0
如果程序崩溃了,它将不会返回任何值。这将由操作系统来处理,但C标准并没有说明应该发生什么。在调用程序时,行为可以描述如下:
int mainWrapper() {
    int ret;
    try {
        ret = main();
    }
    catch(Exception e) {
        ret = // Some value that may or may not depend on what 
              // happened and might even be random
    }
    return ret;
}

当你在机器码中调用函数时,实际上发生的是你只是存储了代码中某个位置的地址,然后跳转到你想要执行的代码。该代码可能对一些寄存器包含你想要传递给该函数的参数做出一些假设。如果你忘记加载这些寄存器,代码将使用其中任何内容而不知道你忘记发送参数。当函数结束时也是同样的情况。这发生在机器码遇到某个返回指令时。该指令将跳回我们调用它的地方。如果之后的代码期望函数返回某些值,它基本上只会希望函数将其返回值存储在正确的位置,然后读取它,而不知道是否真的如此。

所以简短的答案是它可能包含随机值或由操作系统决定的某些值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接