标准C功能:检查-1或0?

时间:2010-10-01 04:38:50

标签: c++ c return-value conventions correctness

许多标准C和POSIX函数返回-1表示错误,0表示成功,例如truncatefflushmsync等。< / p>

int ret = truncate("/some/file", 42);

使用ret != -1ret == 0检查成功是否更好?为什么?

我的想法

我的经验是大多数人检查错误情况(ret != -1),因为通常只有一个(考虑错误时返回NULLEOF的函数)。但事后看来,人们可以看到这些函数可以从直接返回errno中受益(其中0被认为没有错误)。

还担心函数会返回0-1以外的函数,或者稍后会添加其他返回值。在这些情况下,测试表示成功的“最紧密”值范围是有意义的(ret == 0)。

Update0

我的一个假设是,人们都知道EOF通常被定义为-1

9 个答案:

答案 0 :(得分:8)

这取决于函数是C标准库函数还是POSIX函数。 C函数没有统一的返回码标准,所以我会根据具体情况使用最有意义的测试。

另一方面,POSIX更加一致。几乎所有POSIX函数都被定义为返回-1,并在errno中提供更具体的错误代码。有些函数只返回0表示成功,而其他函数则有很多成功值。例如,open()返回文件描述符,read()返回读取的字节数等。

为了保持一致性,我喜欢在调用POSIX函数时始终使用相同的测试:不要测试成功,测试失败。今天在错误时返回-1的POSIX函数将始终返回-1,因此我将对所有这些函数使用两个检查之一:

if (ret == -1) {
    perror(...);
}

// or

if (ret < 0) {
    perror(...);
}

(我更喜欢第一个,但第二个更普遍的不会打扰我。)

答案 1 :(得分:3)

比较truncatefflush的手册页,两者都成功返回0,但返回错误的不同值(truncate - &gt; -1,fflush - &gt; EOF)。所以我要检查0。

答案 2 :(得分:3)

在我看来,这实际上取决于你需要做什么以及返回值的范围。

接听一个成功值和许多失败值的电话。对于成功的返回值,==!=通常比检查任何失败值更容易。在这种情况下,如果您需要,例如,记录并返回或在发生故障时抛出,您将对!= success进行测试。

在一对一的通话中,所需的行为更为重要,因此我建议选择更具可读性。如果您的代码需要做出反应并可能在失败时返回,请检查== failure而不是!= success。前者更具可读性,因为它需要一步思考,故障常数可能有助于命名。

您可能还想考虑哪个更有可能并首先处理,或者在数值上更大或更小。

在您的情况下,如果两个函数共享一个成功代码并且具有不同的失败代码,那么它可能会更具可读性。我同意在两种情况下对== 0的测试看起来会更好,但这实际上取决于调用之间的代码量。如果你有几十行,可读性可能没有太大差别。如果它非常接近,您甚至可以将结果组合在一起并为自己节省几个步骤。

答案 3 :(得分:2)

Cert guidelines似乎更喜欢“!= 0”检查,因为它们在许多示例代码段中都有效。

答案 4 :(得分:2)

请务必查看手册页以获取返回代码。

通常0表示成功,但存在例外printf()

检查man 2 intro是否有errnos和系统调用的错误代码。

答案 5 :(得分:2)

无论你做什么,都不要用

来快速测试成功
if (!ret) 

令人困惑的是,某人(包括你自己)稍后误读它作为失败的测试。通常使用显式测试会更好。

答案 6 :(得分:1)

如果定义为0表示成功,并且您想要检查成功那么您应该检查等值为0.(除了剪切可读性之外没有其他原因)

答案 7 :(得分:1)

对于大多数POSIX API函数,负值是错误。所以我用if (ret < 0)测试失败。

答案 8 :(得分:0)

我的经验法则是,像这样的函数通过返回值返回错误代码(或者只是发生错误)。因此,对我而言,返回值为0意味着没有任何类型的返回并且没有发生错误。因此,如果我想测试函数是否成功,我只检查返回值是否为0,如果不是只检查错误值是什么,并相应地处理它。