我应该从C函数返回真/假值吗?

我应该从C函数返回真/假值吗?,c,return-value,C,Return Value,在用C语言编程了几年之后,我意识到我一直忽略了从函数返回零表示成功的C约定。在我看来,这个约定在语义上是错误的,因为零当然是错误的。问题是我喜欢将函数命名为is\u valid\u foobar(),为了适应“false意味着成功”的惯例,我不得不更加模糊。。。 而不是: if ( ! is_valid_foobar() ) { return (error); } 其他程序员写道: if ( validate_foobar() ) { return (error); } 我

在用C语言编程了几年之后,我意识到我一直忽略了从函数返回零表示成功的C约定。在我看来,这个约定在语义上是错误的,因为零当然是错误的。问题是我喜欢将函数命名为
is\u valid\u foobar()
,为了适应“false意味着成功”的惯例,我不得不更加模糊。。。 而不是:

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;
}
int是有效的\u foobar(int foobar){
如果(foobar<允许的最大值){
返回TRUE;
}
返回FALSE;
}
实际上,我还没有在代码审查中受到任何批评。所以我认为这不是一个可怕的习惯,但它是“非传统的”。我很好奇人们怎么想


我对函数名和变量名的选择非常谨慎,一个典型的评论是“代码非常清晰”,而且我根本不需要输入额外的
位于函数调用的前面。但是你说什么呢,哦,S.O.的伟大人物们?

我不确定我是否同意有一种惯例“从函数返回零表示成功。”

好吧,惯例是零是假的,在谓词的情况下所有非零都是真的

但是,这个约定应该只适用于返回布尔值的明显谓词(例如,true/false)。如果函数的主要目标不是返回布尔值(例如printf、fopen等),则返回值用于指示故障原因,然后可以采用UNIX约定“静默或0,除非出现问题”

至于返回值,使用固定返回值没有什么错,它使一切都更方便


最大的风险是,IMHO,许多人声明自己的常量,当其他人使用相同的文件时,您开始与他们自己的常量发生冲突。因此,你的真/假与其他人的真/假冲突。

这与其说是C约定,不如说是UN*X shell约定。考虑标准的C IasalpHAd()、ISDigE()等函数。它们都返回非零表示成功。底线:在C语言中,“true”是非零的。

我认为两者都是正确的,因为目的不同:

如果您正在执行一个简单的go/no-go验证,例如is_numeric(),那么true和false可以很好地工作

更详细地说,0==成功范例非常有用,因为它允许返回多个错误条件


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

该约定与您的想法不完全一致。进程应以0状态退出以表示成功,返回错误代码的函数通常使用0表示“无错误”。但是作为一个布尔值,0应该表示false,非零应该表示true。使用0表示布尔真有一天会在日常WTF中使用。

特别是当您将函数命名为_foo()时,标准C字符函数(isdigit()、isupper()等)是一个很好的先例,可以按照您的方式使用。

C没有布尔的概念,除了0为假,其他都为真

返回0的想法来自于有一个指示失败原因的返回代码。如果您没有执行返回代码,那么将1和0视为true和false没有错。毕竟,TRUE和FALSE只是C中1和0的typedef

但这应该有很好的文档记录,函数注释应该明确地说“返回TRUE或FALSE”


您还可以编写if(is\u invalid\u foobar()),这可以使语句易于理解,并且在语义上仍然正确。

只有当它灼伤您时才是糟糕的。如果你从来没有发现任何漏洞,我会说你没事。更重要的是,函数上方的注释以“为…返回零”开头


“非零是错误”约定在试图说明原因时与错误标志一起使用

我编程C已经有一段时间了,但我想你在这里谈论的是两种不同的函数:

  • is_foo
    是一个函数,用于检查某些属性foo并返回
    0
    false
    )或非
    0
    true
    )以指示该属性的布尔值。调用这些函数时,不需要任何错误状态(如果发生错误,则映射到其中一个值)
  • foo
    是一个执行操作foo的函数。成功时返回
    0
    ,错误时返回非
    0

对我来说,实际检查0似乎更自然,而且编译器会对其进行优化,所以我喜欢编写示例

如果(检查_foo==0)
//执行某项操作

通过函数返回值--对与错或成功与错误的约定:

  • API等显示返回值为0的成功和返回值=非零错误值的失败
  • 如果事情是真的;函数返回1。例如,如果堆栈为空,isStackEmpty()将返回1

  • 返回1或0仍然是完全任意的。只要保持一致,如果有错误代码,至少要在某个地方注释它们的意思。

    正确-如果您不喜欢直接使用0来获得成功,那么框架或平台通常会提供类似于成功或(有趣的名称)错误\u成功宏/值的内容(以及相应的错误代码名称)这种用法还允许使用公式“if(int e=foo()){/*handle errors*/};”,对于那些在功能更丰富的语言上长大的人来说,它可能看起来很笨拙,但按照c标准,它是干净而流畅的。此外,在Unix/Linux中,这些约定适用于