在 C++ 程序的主函数中,`return 0` 是啥意思? [复制]

Posted

技术标签:

【中文标题】在 C++ 程序的主函数中,`return 0` 是啥意思? [复制]【英文标题】:In the main function of a C++ program, what does `return 0` do and mean? [duplicate]在 C++ 程序的主函数中,`return 0` 是什么意思? [复制] 【发布时间】:2012-01-31 13:46:08 【问题描述】:

可能重复:What is the proper declaration of main?

没有特别引用任何代码,我正在寻找对以下示例的解释:

#include <iostream>

int main()

    std::cout << "Hello world" << std::endl;
    return 0;

我不明白return 0 做了什么。你能用尽可能简单的英语解释一下吗?

【问题讨论】:

简单的英语:函数main返回值0。 C++ 标准描述了宿主环境如何解释它。 在 Unix shell 中,它可以让你判断命令是否成功,如果失败,可能会告诉你为什么失败。如果退出状态(从main() 返回的值或指定为exit()_exit()_Exit() 的参数)为零,则调用环境(shell)将其解释为成功。如果传递的值为EXIT_FAILURE,则调用环境会将其解释为失败。 Unix 允许退出状态的值为 0..255(尽管有时将其解释为 -128..+127)。在大多数 shell 中,您可以在 $? 中获取实际值。信号使事情复杂化。 解释:您计算机上的某个进程(A)启动了另一个进程(B)。当 B 退出时,它总是会在某处存储一种“退出状态”(这是 main 返回的内容,或者您​​的程序实际作为参数提供给 exit 函数的内容)。父进程 (A) 可以读取该值,并相对于它采取行动:例如:Windows“.bat”脚本可能会读取 %ERRORLEVEL% 事物并对其采取行动。一个 UNIX shell 脚本可能会读取 $?事情,并采取行动。 当我们谈到这个主题时,***.com/questions/3309042/what-does-main-return 是一个完全不同的问题。 好的,谢谢 Johnsyweb。 【参考方案1】:

这定义了进程的exit status。尽管是 int,但在类 Unix 系统上,该值始终在 0-255 范围内(请参阅 Exit and Exit Status)。在 Microsoft 系统上,您可以使用 32-bit signed integers as exit codes,您可以使用 %ERRORLEVEL% 进行检查。为了便携性,我建议坚持使用 0-255 范围。

这是一个简单的例子:

$ cat -n exit_code.cpp 
     1  int main()
     2  
     3      return 42;
     4  
     5  

构建:

$ make exit_code
g++ exit_code.cpp -o exit_code

运行(在 bash 中):

$ ./exit_code

检查退出状态:

$ echo $?
42

通常,状态为零表示成功和非零失败。这在 shell 脚本等中很有用,以指示故障级别(如果有):

$ ./exit_code
exit_status=$?
if [[ $exit_status ]] ; then
    echo "The process failed with status $exit_status."
else
    echo "Success!"
fi
The process failed with status 42.

按照下面的cmets...

在标准C++header &lt;cstdlib&gt;中,定义了以下宏:

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

但是,GNU C Library documentation 的 Exit Status 部分描述了相同的宏,明智地指出:

可移植性说明:一些非 POSIX 系统对退出状态值使用不同的约定。为了获得更大的可移植性,您可以使用宏 EXIT_SUCCESS 和 EXIT_FAILURE 分别作为成功和失败的常规状态值。它们在文件 stdlib.h 中声明。

【讨论】:

谢谢!但是编码员为什么要定义错误代码呢? +1 得到一个很好的明确答案 :) 作为 OP 的一个侧面,虽然 42 在这里很好地说明了这一点,但我想我记得说唯一的可移植返回码是 0,EXIT_SUCCESS和 EXIT_FAILURE - 如果您希望代码可移植,请不要使用其他东西。 @frunsi:请您引用该规则的标准吗? @Johnsyweb:是的,但是 AFAIK 这三个是 ISO C++ 标准中提到的三个可移植返回码。可悲的是,我没有这个临时的参考,尽管快速谷歌的“c++ 便携式返回主要退出成功”似乎确实让我相信我想说的话。此外,有用和便携不一定是一回事。 感谢各位的评论。希望我更新的帖子@DustinStalin 有足够的信息来回答他的问题。【参考方案2】:

一般returning

每个函数都有一个返回类型

在下面的例子中,类型是void,这是一个没有值的“不完整类型”;使用 this 作为返回类型意味着函数没有返回值:

void foo() 
   std::cout << "Hello world\n";

但是,在下面的示例中,返回类型是int

int foo() 
   return 3;

return 语句确定调用函数foo 的值将计算为什么值。因此,std::cout &lt;&lt; foo() 将导致“3”被打印到标准输出。


return来自main,具体来说

当有问题的函数恰好是“main”函数,或者程序的入口点时,它有点特别,因为“main”函数的“返回值”被认为是程序的“退出代码” — 它告诉调用环境(例如终端会话)程序的执行是否被认为是成功的。必须是int0 的值在这里表示“一切正常”:

值得注意的是,您实际上可以在“main”函数中完全省略return 0;,因为它将被隐式包含。但是,如果您想 return 1; 或其他一些值,这对您没有多大帮助,并且它不会与其他功能一起使用。


引文

[C++11: 3.6.1/5]: main 中的 return 语句具有以下效果 离开主要功能(自动销毁任何对象 存储持续时间)并调用std::exit,返回值作为 论点。 如果控制到达main 的末尾而没有遇到 return 语句,效果就是执行return 0;

[C++11: 18.5/8]:

       [[noreturn]] void exit(int status)

函数exit() 在此国际标准中有其他行为

首先,销毁具有线程存储持续时间并与当前线程关联的对象。 接下来,销毁具有静态存储持续时间的对象,并调用通过调用atexit 注册的函数。销毁和调用的顺序见 3.6.3。 (调用 exit() 不会破坏自动对象。) 如果由于该函数没有为抛出的异常提供处理程序而控制退出由 exit 调用的已注册函数,则应调用 terminate() (15.5.1)。 接下来,带有未写入缓冲数据的所有打开的 C 流(由 &lt;cstdio&gt; 中声明的函数签名介导)被刷新,所有打开的 C 流都被关闭,并且通过调用 tmpfile() 创建的所有文件都被删除。李> 最后,控制权返回到宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,则返回状态未成功终止的实现定义形式。否则返回的状态是实现定义的。

引导笔记

我建议使用these resources 之一,因为这类事情在任何经过​​同行评审的C++ 书籍中都有适当的解释; YouTube 教程不是学习 C++ 的好方法,Stack Overflow 的贡献者通常希望你有一本像样的书来形成你之前的研究,然后再寻求帮助。

【讨论】:

对于托管程序,没有什么“常规”——标准非常清楚地描述了 main 的返回值应该达到的目标...... @TomalakGeret'kal: 18.5 "最后,控制权返回给宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,返回状态不成功终止的实现定义的形式。否则返回的状态是实现定义的。" @frunsi:它总是有一个类型,它可能并不总是返回一个void 是一种类型。 @frunsi: C++11 §3.9.1\9 "void 类型有一组空值。void 类型是不完整的类型,无法完成。它用作返回不返回值的函数的类型。” C++ 标准对我来说似乎很清楚 void 确实是一种类型。我可以看到将“void”视为无类型构造是多么容易,所以这个错误是可以理解的。 返回类型为 void 的函数表示没有返回值的函数。 void not 不代表没有类型。它代表没有【参考方案3】:

使用它是因为您可以将程序用作命令行工具。如果有另一个进程在等待你的程序的输出,你可以选择如果一切都成功则返回 0,如果有错误则返回 -1 或任何其他常量,根据你想要传达的内容。

【讨论】:

【参考方案4】:

想想你的老板告诉你去取邮件。收到邮件后,你告诉老板一切都好。

操作系统是老板,程序是你。而return 0 所做的只是告诉操作系统一切正常。

【讨论】:

这让我畏缩了一些慢性病。我的错,不是你的。 使用这个类比,1 会是什么?邮件被老鹰拦截了,所以在你清除老鹰之前无法完成工作?【参考方案5】:

在windows下你可以按如下方式测试返回值(在批处理脚本中):

MyAppTest.exe
@if "%ERRORLEVEL%" == "0" goto success
 echo Failure
 goto end
:success
 echo Success
:end

【讨论】:

【参考方案6】:

main()返回与调用std::exit()并将返回值作为status参数传递的效果相同。

std::exit 的行为在第 18.5 节 ([support.start.term]) 中有详细说明,并描述了状态码:

最后,控制权返回到宿主环境。如果状态为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果状态为EXIT_FAILURE,则返回状态未成功终止的实现定义形式。否则返回的状态是实现定义的。

【讨论】:

【参考方案7】:

return 用于转义函数。返回值 0 只是允许它以代码 0 退出。此外,返回 0 表示应用程序成功退出。

【讨论】:

【参考方案8】:

取决于操作系统,但退出代码 0 表示在 UNIX、VMS 和 Windows 上成功

【讨论】:

【参考方案9】:

主函数的返回值被返回给调用应用程序或进程(很多时候这是一个 shell 脚本)。返回值用于指示应用程序的退出状态。

对于返回值应该是什么没有严格的规则,但按照惯例,返回值为零表示正常的应用程序退出。任何非零值都表示应用程序异常退出。

【讨论】:

【参考方案10】:

在像您这样的简单应用程序中,返回值没有任何意义。如果有一个观察过程(例如一个程序启动另一个程序),这可能是一种获取状态或错误代码的简单方法。

对于没有状态或错误代码的简单应用程序,大多数人return 0 表示正常的应用程序退出(通常是成功),return 1 如果应用程序退出。无法正确执行。

【讨论】:

【参考方案11】:

0 是一个整数。

你的主函数必须返回一个整数。

看看:

int main()

int代表整数,在这种情况下return返回0:一个整数来终止程序。

通常对于一个错误你必须返回1; 0 是成功的常规值。

【讨论】:

【参考方案12】:

在现代操作系统上,每个程序都会以特定的“退出代码”退出。

免责声明 NO 1.:该概念的实际规范(根本没有退出代码)完全超出了任何编程语言规范的范围。所以:任何人再次向我询问对标准的引用,都可以退回到自己,并暂时考虑一个更好的答案。

DISPLAIMER NO 2.:这些退出代码的实际值未在非实际“编程语言规范”中指定,因为这超出了“编程语言规范”的范围。

长期以来,实践表明,退出代码“0”表示“成功”,任何其他代码都表示错误...

【讨论】:

以上是关于在 C++ 程序的主函数中,`return 0` 是啥意思? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 程序中调用 Python 函数

函数在`if`的分支中返回与`if`之外,在C++中

每天一个编程小技巧C++ return:使函数立即结束!

每天一个编程小技巧C++ return:使函数立即结束!

每天一个编程小技巧C++ return:使函数立即结束!

C++获得程序的调用栈的几种方法