我应该从C函数返回真/假值吗?
在用C语言编程了几年之后,我意识到我一直忽略了从函数返回零表示成功的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); } 我
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中,这些约定适用于