返回0的基本原理是C / C ++中的默认值

有没有理由将零用作“默认”函数返回值? 我注意到stdlib和几乎所有其他地方的几个函数,当没有返回正确的数字(例如pow(),strcpy())或错误(负数)时,只返回零。

在看到几个用否定逻辑进行的测试后,我感到很好奇。 很混乱。

为什么不返回1,或0xff,或任何正数?

理由是你要区分对应于不同错误的所有可能(负)返回值的集合,以及所有正常情况的唯一情况。 追求这种区别的最简单,最简洁和最C-ish的方法是逻辑测试,因为在C中所有整数都是“真”,除了零,你想要返回零表示“唯一的情况”,即你想要零作为“好”值。

同样的推理也适用于Unix程序的返回值,但实际上在Unix shell脚本的测试中,逻辑是反转的:返回值0意味着“真”(例如,查看/ bin /的返回值)真正)。

最初,C没有“无效”。 如果函数没有返回任何内容,则只需将声明中的返回类型留空即可。 但这意味着,它返回了一个int。

所以,一切都返回了一些东西,即使它没有任何意义。 并且,如果您没有专门提供返回值,则编译器用于返回值的寄存器中发生的任何值都将成为函数的返回值。

// Perfectly good K&R C code. NoReturn() { // do stuff; return; } int unknownValue = NoReturn(); 

为了避免出现问题,人们将其清零。

在shell脚本中,0表示true,其中另一个数字通常表示错误代码。 从主应用程序返回0表示一切都成功。 可以将相同的逻辑应用于库代码。

它也可能只是它们没有返回任何东西,它被解释为0.(基本上是相同的概念。)

另一个(次要)原因与机器级速度和代码大小有关。

在大多数处理器中,任何导致零的操作都会自动设置零标志,并且有一个非常便宜的操作来跳过零标志。

换句话说,如果最后一次机器操作(例如,PUSH)使我们为零,我们所需要的只是一个零跳或零跳。

另一方面,如果我们针对其他值测试事物,那么我们必须将该值移动到寄存器中,运行基本上减去这两个数字的比较操作,并且相等导致我们的零。

因为Bash和大多数其他UNIX shell环境将0视为成功,将-x视为系统错误,将x视为用户定义的错误。

可能有一堆被遗忘的历史可以追溯到一切都是用asm写的。 通常,测试零比其他特定值更容易。

我可能错了,但我认为这主要是出于历史原因(歇斯底里的葡萄干?)。 我相信K&R C(pre-ANSI)没有void类型,因此编写一个没有返回任何有趣内容的函数的逻辑方法是让它返回0。

如果我错了,肯定会有人在这里纠正我…… 🙂

我的理解是它与系统调用的行为有关。

考虑open()系统调用; 如果成功,则返回非负整数,即创建的文件描述符。 但是,在汇编程序级别(其中有一个特殊的非C指令陷入内核),当返回错误时,它将返回为负值。 当它检测到错误返回时,系统调用周围的C代码包装器将否定值存储到errno (因此errno具有正值),并且函数返回-1。

对于其他一些系统调用,汇编程序级别的否定返回代码仍然被否定并放入errno并返回-1。 但是,这些系统调用没有特殊的返回值,因此选择零表示成功。 显然,有各种各样的系统调用,但大多数都设法适应这些约定。 例如, stat()及其亲属返回一个结构,但是指向该结构的指针作为输入参数传递,返回值为0或-1状态。 甚至signal()管理它; -1是SIG_DFL,0是SIG_IGN,其他值是函数指针。 有一些没有错误返回的系统调用 – getpid()getuid()等等。

然后,这个零指示成功机制由其他不是系统调用的函数模拟。

通常,返回码0指定您的程序正常结束且一切正常。 (您可以记住这是“零错误”,虽然由于技术原因,您不能使用程序找到的错误数作为返回代码。请参阅样式。)除0以外的返回代码表示发生了某种错误。 如果您的代码在遇到错误时终止,请使用exit,并指定非零返回码。 资源

因为0是假的而且在C / C ++中是null,并且当发生这种情况时你可以做出方便的捷径。

这是因为当从UNIX shell使用时,返回0的命令表示成功。

任何其他值表示失败。 正如保罗贝茨所指出的那样,正面和负面的价值可以界定错误的起源,但这只是一种惯例,而不是绝对的。 用户应用程序可能返回负值而没有任何不良后果(除了它向shell指示应用程序失败)。

除了以前的海报所做的所有细节之外,当函数成功返回0时,它还会大大清理代码。

考虑:

 if ( somefunc() ) { // handle error } 

比以下更清洁:

 if ( !somefunc() ) { // handle error } 

要么:

 if ( somefunc() == somevalue ) { // handle error } 

这个论点因为:BOOL isTrue = TRUE; 或boolean isTrue = true; isTrue = 1除1之外的所有内容都被视为FALSE(包括0)。