main函数的返回值范围
Posted
技术标签:
【中文标题】main函数的返回值范围【英文标题】:Return value range of the main function 【发布时间】:2011-07-06 04:11:11 【问题描述】:标准对主要返回值范围有何看法? 最多只能说 255 个?
因为
int main(void)
return 256;
echo $? ; # out 0
【问题讨论】:
另见ExitCodes greater than 255 — possible? 【参考方案1】:标准没有说。 0
、EXIT_SUCCESS
和 EXIT_FAILURE
具有(某种)特定的含义。其他任何事情都取决于实现。
目前,大多数基于 Unix 的系统仅支持 8 位返回值。 Windows 支持(至少)32 位返回值。我没有检查 64 位 Windows 是否支持 64 位返回值,但我比较怀疑,因为即使 64 位 Windows 通常仍然使用 32 位 int。
【讨论】:
在 64 位 Windows 上我尝试了cmd /c "exit 4000000000"
然后 echo %errorlevel%
并返回 -294967296 => 32 位
POSIX 标准确实 非常清楚地定义了这一点:pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html
@MikeFrysinger:它说:“......完整的值应从 waitid() 和传递给 SIGCHLD.v 的信号处理程序的 siginfo_t 中可用”,但没有说任何关于该“完整值”是 16、32 还是 64 位。我看不到对 int 大小的特定于 POSIX 的定义的交叉引用,并且 C 标准允许上述任何一种。这可能是关闭进程时需要进行的 other 清理的一个不错的定义,但就返回值中的位数而言(充其量)似乎是平庸的。
虽然您是正确的,但它们并没有明确规定 int 的大小,POSIX 和 C 标准都要求 INT_MAX 必须至少为 2147483647 (2^31-1) 并且 INT_MIN 必须在大多数 -2147483647 (-2^31+1),并且“int”类型的对象必须能够表示 [INT_MIN, INT_MAX],所以我认为可以安全地假设 sizeof(int) 是(至少)32 - 任何 POSIX 兼容系统上的位。 pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
你也可以这样看:main的返回值是一个“int”。 POSIX (2016+) 将其全部价值定义为在使用 waitid 或 sigaction/etc...+SA_SIGINFO 时可供父进程使用。【参考方案2】:
正如其他人所说,C 和 C++ 标准除了声明之外根本不限制返回值
main()
返回一个 int
(具有实现定义的大小),并且
零(或EXIT_SUCCESS
)是成功返回,EXIT_FAILURE
是不成功返回。
它确实指定了一个没有明确返回值的main()
被视为返回零。
在这种情况下,返回值的解释取决于等待进程完成的进程(通过调用wait()
、waitpid()
或waitid()
)。 wait()
和 waitpid()
是较旧的 POSIX 函数,它们仅指定 the least significant eight bits of the return value shall be available to a waiting parent process。 POSIX:2008 标准添加了waitid()
作为通用等待方法,可以访问子进程的完全退出状态。
在 fork 子进程后,父进程调用 wait*()
函数之一进入休眠状态,直到 fork 进程完成(例如,从 main()
返回,调用 exit()
或 abort()
或其他东西)。 wait()
和waitpid()
函数通过指向整数的指针返回状态。调用者使用WIFEXITED(status_val)
和WEXITSTATUS(status_val)
宏提取实际退出状态。后者由 POSIX 定义,需要返回 the low-order 8 bits of the status argument。 waitid()
函数使用指向siginfo_t
结构的指针来返回进程的状态信息。 si_status
成员包含Status Information 中描述的完整状态值。
基本上,退出状态的值在旁观者的眼中。 ANSI/ISO 规范是开放式的。 POSIX 套件有多种方法可以等待进程完成并获取其退出状态。 POSIX 还将spawn()
定义为exec()
的轻量级版本,它对退出状态值有自己的一组约束。 Shell 有进一步限制结果值的习惯——GNU's bash 将返回状态限制为 7 位,POSIX-compliant shell 将退出状态值限制为 8 位。 FWIW,大多数人都同意将您的返回值限制为lower than 64 seems to be safe。
【讨论】:
【参考方案3】:在类 Unix 系统上,退出代码是 0 到 255 之间的数字。你可以返回任何东西,但在 Linux 中它是修改为 256。看看here 以获得关于 Linux 返回码的一个很好的解释。还有一个Wikipedia article on the topic 简要介绍了 Windows 的退出代码。
【讨论】:
说“模”是一种误导,因为它实际上是一个 8 位掩码。 exit(-1) 对大多数调用者会产生 255 的值(因为 -1&0xff == 255),但 -1%256 == -1,而不是 255。是的,它从有符号的 32 位变为无符号的 8 位. @MikeFrysinger “模”是正确的术语。您在此处描述的%
运算符是除法的余数,但大多数现代编程语言实际上使用 %
进行取模,这适用。
Modulo 不是我已经解释过的正确术语。 %
== modulo 的事实不相关,因为手头的操作不是 %
。【参考方案4】:
C 标准对退出代码没有特别的限制,关于main
的返回值的段落代表了关于exit()
函数的文档,它反过来说:
如果status 的值为零或
EXIT_SUCCESS
,则返回成功终止状态的实现定义形式。如果status的值为EXIT_FAILURE
,则返回一个实现定义的状态不成功终止形式。否则返回的状态是实现定义的。
除了EXIT_SUCCESS
/EXIT_FAILURE
准则之外,它基本上意味着“随心所欲”。 :)
正如在一条评论中所说,在 POSIX 系统上实际上只考虑退出代码的低 8 位这一事实只是一种 UNIX 主义,源自 wait
系统调用的设计方式(退出状态必须被打包在wait
返回值的低8位),与C标准无关。
一个反例是 Windows,其中考虑传递给 exit
/return
的整个值(只要它不大于 DWORD
1,但我不认为他们会让int
比DWORD
大,这会破坏很多代码)。
1、因为为返回这个值而保留的
GetExitCodeProcess
参数是DWORD *
。
【讨论】:
事实上ExitProcess函数接收到UINT
【参考方案5】:
在 Unix 上,等待系统调用设置一个 int 类型的状态值打包为 具有各种类型孩子的位域 终止信息。如果孩子 通过退出终止(如确定 通过 WIFEXITED 宏;通常 另一种选择是它死于 未捕获的信号),SUS指定 状态值的低 8 位 包含退出状态;这个可以 使用 WEXITSTATUS 检索 wait.h 中的宏。因此,在 Unix 退出状态仅限于值 0-255,无符号8位范围 整数。
类 Unix 系统通常使用 成功和非零的约定 零错误。一些约定 已经发展到相对 各种错误代码的含义;为了 示例 GNU 建议使用 高位设置被保留 严重错误,而 FreeBSD 有 记录了一组广泛的 首选的解释。
C99 标准只定义了 0 和 1。但是,允许使用其他值。
请参阅Exit Status wiki 了解更多信息。
【讨论】:
我不记得曾在标准的任何地方看到过1
的值。在 ANSI/ISO 标准中,只有 0
、EXIT_SUCCESS
和 EXIT_FAILURE
被明确称为状态值。
@D.Shawley:你是对的。但我从未见过 EXIT_SUCCESS 与 #define EXIT_SUCCESS 0
或 #define EXIT_FAILURE 1
的 EXIT_FAILURE 不同。【参考方案6】:
您返回类型int
。您应该能够返回可以存储在int
中的任何值。 int
的确切大小取决于实现,所以我不能给你一个确切的范围。
【讨论】:
话虽如此,您的 shell 可能支持的返回值范围有限。然而,这不是 C 标准的一部分。 即使返回类型是int,也只有低8位包含退出状态。 @Vlad:这只是一个 UNIX 主义,标准没有说明它。 @Vlad Lazarenko-根据 C 标准,这是不正确的。那是 POSIX 特定的行为。 OP 询问了 standard 的规定。 我实际上告诉了 C 标准的规定,0 和 1 :-) 由于问题是在 unix 范围内提出的 ($?
),我说为什么 0-255...【参考方案7】:
5.1.2.2.3 程序终止 1 如果主函数的返回类型是 与 int 兼容的类型,返回 从最初的调用到 main 函数相当于调用 退出函数并返回值 由 main 函数作为其参数; 10) 到达终止 main 函数返回值 0。如果 返回类型不兼容 int,返回的终止状态 到宿主环境是未指定的
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
即,它不需要返回任何东西。然而,它强烈地说明了通常的定义是什么。几乎暗示它们是标准的,但有一张免狱卡,这意味着它可以是任何东西。
【讨论】:
以上是关于main函数的返回值范围的主要内容,如果未能解决你的问题,请参考以下文章