我应该从C函数返回TRUE / FALSE值吗?

时间:2009-02-17 22:42:08

标签: c return-value

在C中编程好几年后,我意识到我一直忽略了从函数返回零来表示成功的C约定。这个惯例对我来说在语义上是错误的,因为零当然是错误的。问题是我喜欢命名像is_valid_foobar()这样的函数,为了适应'虚假意味着成功'的惯例,我必须更加模糊...... 而不是:

if ( ! is_valid_foobar() ) {
    return (error);
}

其他程序员写道:

if ( validate_foobar() ) {
     return (error);
}

我的实现如下:

int is_valid_foobar (int foobar ) {
     if ( foobar < MAX_ALLOWED ) {
          return TRUE;
      }
      return FALSE;
}

在代码审查中,我实际上并未发现任何问题。所以我认为这不是一个可怕的习惯,但它是“非常规的”。我很好奇人们的想法。

我对我为函数和变量名做出的选择非常谨慎,典型的评论评论是“代码非常清晰”,而且根本不需要输入额外的{{ {1}}在函数调用的前面。但是,你怎么说,哦,强大的S.O?

11 个答案:

答案 0 :(得分:19)

我说两者都是正确的,出于不同的目的:

如果您正在执行简单的go / no-go验证,例如is_numeric(),然后true和false很好地工作。

对于更精细的内容,0 ==成功范例是有用的,因为它允许返回多个错误条件。

在这种情况下,调用者可以简单地对0进行测试,或者检查非0返回以获得更具体的失败解释。例如文件打开调用可能由于不存在,权限不足等原因而失败。

答案 1 :(得分:11)

这个惯例并不完全是你想象的。进程应以0状态退出以指示成功,而返回错误代码的函数通常使用0来表示“无错误”。但作为布尔值,0应该表示false,非零表示true。要使用0表示布尔值,有一天你可以登上The Daily WTF。

答案 2 :(得分:6)

我编程C已经有一段时间了,但我认为你在谈论两种不同的功能:

  • is_foo是一个函数,用于检查某些属性foo并返回0false)或非 - 0true)以指示布尔值该财产的价值。调用这些函数时,不会出现错误状态(如果发生错误状态,则会映射到其中一个值)。
  • foo是执行动作foo的函数。它会在成功时返回0,在错误时返回非0值。

答案 3 :(得分:3)

我不确定我是否同意“从函数返回零以表示成功”的约定。

AFAIK,惯例是零是假的,并且在谓词的情况下所有非零都是真的。

但是,此约定仅适用于返回布尔值的明显谓词(例如,true / false)。如果函数的主要目标不是返回布尔值(例如,printf,fopen等),则返回值用于指示失败原因,然后您可以采用UNIX约定“silent或0”除非有一个问题“。

对于返回值,使用固定返回值没有任何问题,它使一切更加方便。

很大的风险,恕我直言,许多人声明他们自己的常量,当其他人使用相同的文件时,你开始与他们自己的常量发生冲突。所以你的TRUE / FALSE与其他人的TRUE / FALSE相冲突。

答案 4 :(得分:3)

特别是当您将函数命名为is_foo()时,标准C字符函数(isdigit(),isupper()等)是您按照自己的方式进行操作的良好先例。

答案 5 :(得分:3)

C没有布尔的概念,除了0是假的,其他任何东西都是真的。

返回0的想法来自于返回代码,指示失败是什么。如果你没有做返回码,那么将1和0视为真和假是没有错的。毕竟,TRUE和FALSE只是1和0的typedef。

这应该有详细记录,你的函数注释应该说明确“返回TRUE或FALSE”。

你也可以编写if(is_invalid_foobar()),这可以使语句易于理解并且在语义上仍然正确。

答案 6 :(得分:2)

这不是一个像UN * X shell那样的C约定。考虑标准C iasalpha(),isdigit()等函数。它们都返回非零值表示成功。底线:在C'中'是'非零。

答案 7 :(得分:0)

如果它烧伤你,那就太糟糕了。如果你从来没有追查任何错误,我会说你没事。更重要的是,函数上面的注释以“为...返回零”

开头

在尝试说出为什么以及错误标志时,会使用“非零是错误”约定。

答案 8 :(得分:0)

对我来说,实际检查0看起来更自然,编译器无论如何都要对它进行优化,所以我想写例如

if(check_foo == 0)   //做点什么

答案 9 :(得分:0)

按函数返回值 - True和False的约定或成功和错误:

  1. API等显示返回值0成功,失败返回值=非零错误值。
  2. 如果是真的话;函数返回1.例如如果stack为空,isStackEmpty()将返回1。

答案 10 :(得分:0)

返回1或0仍然是完全随意的。只要保持一致,如果有错误代码,至少要评论它们在某处的含义。