C ++返回main()的末尾

时间:2013-08-06 17:41:11

标签: c++

我正在考虑实现我自己的exit()功能,仅用于教育目的。我知道你可以操作地址,如果操作系统允许你(例如操作系统不会让你操纵地址0,它会导致崩溃)。
所以我想为什么不将0发送到该地址return 0返回。

int main(){
// code...
return 0;
}

return 0向操作系统返回'成功',对吧?但是它的地址是什么?我怎么得到它?并且是以这种方式实现的C标准库的实际exit()吗?

8 个答案:

答案 0 :(得分:4)

当您return 0时,您不会返回地址。您将返回 0.当进程返回值0时,它被视为正常终止。您可以返回一个非零值(最多255个),该值可以由调用进程解释为消息。

让我们看一下示例命令grep foobar fubar。如果文件foobar中存在模式fubar,它将返回0(成功)。如果文件foobar中没有fubar,它将返回1。当没有名为fubar的文件时,它将返回2。 rturn值可以在脚本中解释,该脚本使该命令评估失败的成功或原因。

答案 1 :(得分:4)

退出代码(最终)存储在过程控制块中,以便操作系统可以将结果值报告给其他进程。

请参阅http://www.cs.auckland.ac.nz/compsci340s2c/lectures/lecture06.pdf

但是,return语句并不是这样的。您的运行时库实际上像正常函数一样调用main,获取返回值(在Intel上,类型int的返回值将存储在EAX寄存器中),然后请求内核将其写入TCB。 exit()还调用内核来编写TCB的这个成员。

答案 2 :(得分:2)

return 0;中的main在任何地方都像return一样;它 返回到它被调用的地方。你几时开始 一个程序,系统main启动它,但在某些程序启动它 启动地址,执行大量初始化,然后 类似的东西:

exit( main(/*...*/) );

换句话说,exit不会模拟main的回报; 从main来电exit返回。然后退出做了很多 在调用某些特定于系统的功能之前关闭 告诉系统停止进程(在Unix下_exit)。

您无法自己实施exit,因为您无法实现 找到它需要的信息:功能列表 在atexit注册了需要调用的列表 具有静态生命周期的对象的析构函数

答案 3 :(得分:2)

我认为这里的主要困惑是main是C ++程序中发生的第一件也是最后一件事。虽然它是[1]你的程序的第一部分,但是应用程序中通常会有一些代码设置一些东西,解析命令行参数,打开/初始化标准I / O(cin,{{调用cout之前发生的其他类似事件。}}等等。 main本质上只是另一个函数,由C ++运行时功能调用,它“在main之前修复”。

因此,当main返回时,它会返回到调用它的代码,然后清除需要清理的东西(关闭标准I / O通道,以及许多其他类似的东西)通过调用一些OS函数来“终止此过程”来完成。作为“终止此过程”的一部分,(在大多数操作系统中)功能是向操作系统发出“成功或失败”信号的一种方式,因此监视应用程序的其他一些过程可以确定“如果一切顺利”。最终,main(或0如果您在1中使用return 1;)最终会出现这种情况。

[1]如果有静态对象的构造函数是用户代码的一部分,那么这些将在main中的任何代码之前执行[或者至少在main中的任何代码之前执行属于用户的应用程序]被执行。

答案 4 :(得分:1)

您的困惑是因为不了解return的作用。以此功能为例:

int add(int x, int y)
{
   return (x + y);
}

上述函数中的返回值和main函数末尾的return语句完全相同,从语言角度来看它们的含义相同。这意味着将一个整数返回给调用者。调用者从这个值中得到的东西完全是另一件事,它取决于调用者调用所述函数的意图。假设我可以拨打add(7, 9);添加两个GPA成绩,而另一个程序员可能会调用它来查找几个银行账户中所有资金的总和。

现在main被视为一个特殊功能,因为它是操作系统的第一个功能,或者更具体地说是它的加载器,它被称为您的程序。程序完成后,无论main返回什么,都可能意味着基于操作系统语义的任何内容。该值与任何内存地址无关。

旁白:根据标准,在C ++(和C99 onawards)中,return 0;语句可以省略,表示程序成功终止。

答案 5 :(得分:0)

如果理解是正确的,那么将会有一个SIGCHLD信号在退出时发送到主shell,其中包含返回值......这应该在内核销毁PCB时发生......

但是如果你想在退出代码时挂钩某些功能,你可以根据POSIX实现在atexit()注册一个处理程序。

我不认为您可以修改返回值在用户级别传播的方式,因为程序的控制权在另一个进程(您无权访问)中到达PC。

答案 6 :(得分:0)

如果您的C ++ abi库实现符号__cxa_atexit,您可以使用atexit

AFAIK语言并没有真正提供其他安全方式来执行程序停止执行时用户定义的内容。

答案 7 :(得分:0)

当你有function时,它有一个类型。它可以是intvoid或其他。如果函数不是void,那么它必须返回一个值。在我们的示例中,return的{​​{1}}值为main,通常为int代码。惯例是,如果它是0,则没有错误,而其他值是错误代码。