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

时间:2008-12-01 03:27:17

标签: c++ c

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

我看到几个用否定逻辑进行的测试后变得好奇。非常混乱。

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

13 个答案:

答案 0 :(得分:24)

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

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

答案 1 :(得分:19)

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

所以,一切都归还了,即使它没有任何意义。并且,如果您没有专门提供返回值,那么编译器用于返回值的寄存器中的任何值都会成为函数的返回值。

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

int unknownValue = NoReturn();

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:4)

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

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

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

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

如果我错了,肯定会有人在这里纠正我...... :)

答案 7 :(得分:1)

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

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

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

这个零指示成功机制随后被其他函数模拟,这些函数实际上不是系统调用。

答案 8 :(得分:1)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

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

考虑:

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

比以下更清洁:

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

或:

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

答案 12 :(得分:0)

这个论点自那以后就变成了碎片: BOOL isTrue = TRUE; 要么 boolean isTrue = true; isTrue = 1 除1之外的所有内容都被视为FALSE(包括0)。