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

时间:2022-01-26 19:34:12

After programming in C for several years, I realized that I have been ignoring the C convention of returning zero from a function to indicate success. The convention seems semantically wrong to me, as zero is of course false. The problem is I like to name functions like is_valid_foobar(), and in order to accomodate the convention of 'false means success', I would have to be more vague... that is instead of:

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

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

Other programmers write:

其他程序员写道:

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

And my implementation looks like:

我的实现看起来像:

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

I haven't actually caught any flak for this in code reviews. So I'm thinking it's not such a terrible habit, but it is 'unconventional'. I'm curious what people think.

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

I'm very careful about the choices I make for function and variable names, and a typical review comment is "the code is really clear", and further it doesn't bother me at all to have to type an extra ! at the front of the function call. But what sayest thou, oh mighty ones of S.O?

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

11 个解决方案

#1


19  

I'd say both are correct, for different purposes:

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

If you're performing a simple go/no-go validation, e.g. is_numeric(), then true and false work nicely.

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

For something more elaborate, the 0==success paradigm is helpful in that it allows more than one error condition to be returned.

对于更复杂的东西,0 ==成功范例是有用的,因为它允许返回多个错误条件。

In this case, the caller can simply test against 0, or examine the non-0 returns for a more-specific explanation of the failure. e.g. a file open call can fail due to non-existence, insufficient permissions, etc.

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

#2


11  

The convention isn't exactly what you seem to think. Processes should exit with a 0 status to indicate success, and functions that return error codes will often use 0 to indicate "no error". But as a boolean, 0 should mean false and nonzero should mean true. To use 0 for boolean true will get you on The Daily WTF someday.

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

#3


6  

It's been a while since I programmed C, but I think you're talking about two different kinds of functions here:

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

  • is_foo is a functions that checks for some property foo and returns 0 (false) or non-0 (true) to indicate the boolean value of that property. When calling those functions no error state is expected (and if it happens, it's mapped on one of those values).
  • is_foo是一个检查某些属性foo并返回0(false)或非0(true)的函数,以指示该属性的布尔值。调用这些函数时,不会出现错误状态(如果发生错误状态,则会映射到其中一个值)。
  • foo is a function that executes the action foo. It returns 0 on success and a non-0 value on error.
  • foo是一个执行动作foo的函数。成功时返回0,错误时返回非0值。

#4


3  

I am not sure I agree that there is a convention of "returning zero from a function to indicate success."

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

AFAIK, the convention is that zero is false, and all nonzeros are true in the case of predicates.

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

However, this convention should only apply to obvious predicates that return booleans (e.g., true/false). If the primary goal of a function is not to return a boolean value (e.g., printf, fopen, etc.), then the return value is used to indicate failure reasons, and then you can adopt the UNIX convention of "silence or 0 unless there's a problem".

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

As for return values, there is nothing wrong with using fixed return values, it makes everything more convenient.

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

The big risk, IMHO, is that many people declare their own constants, and when others use the same files, you start running into conflicts with their own constants. So your TRUE/FALSE and conflict with somebody else's TRUE/FALSE down the line.

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

#5


3  

Especially when you name your function is_foo(), the standard C character functions (isdigit(), isupper(), etc) are a good precedent for doing it your way.

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

#6


3  

C has no concept of boolean other than 0 being false, and anything else being true.

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

The idea of returning 0 comes from having a return code indicating what the failure is. If you're not doing a return code, then there's nothing wrong with treating 1 and 0 as true and false. After all, TRUE and FALSE are just typedefs for 1 and 0 in C.

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

This should be well documented though, and your function comments should say explicity "Returns TRUE or FALSE".

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

You could also write if (is_invalid_foobar()), that could make the statement easy to understand and still semantically correct.

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

#7


2  

That's not so much a C convention as a UN*X shell one. Consider the Standard C iasalpha(), isdigit() etc functions. They all return non-zero to indicate success. Bottom line: in C 'true' is non-zero.

这不是一个C大会,而是UN * X shell。考虑标准C iasalpha(),isdigit()等函数。它们都返回非零值以表示成功。底线:在C中'真'不为零。

#8


0  

It's only bad if it burns you. If you never trace any bugs to this, I'd say you are OK. What's more important, is the comment above the function that starts with, "Returns zero for..."

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

The "nonzero is an error" convention is used when attempting to say why along with the error flag.

当试图说明为什么以及错误标志时,使用“非零是错误”约定。

#9


0  

to me, actually checking against 0 seems more natural and the compiler optimizes it anyway so i like to write for instance

对我来说,实际检查0似乎更自然,编译器无论如何都优化它,所以我喜欢写例如

if ( check_foo == 0 ) //do something

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

#10


0  

Return value by a function -- conventions for True and False OR Success and Error:

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

  1. An API etc. shows success with return value 0 and failure with return value = non zero error value.
  2. API等显示返回值0成功,失败返回值=非零错误值。
  3. If something is True; functions return 1. E.g. isStackEmpty() will return 1 if stack is empty.
  4. 如果某事是真的;函数返回1.例如如果stack为空,isStackEmpty()将返回1。

#11


0  

It's still completely arbitrary to return 1 or 0. Just be consistent and if there are error codes, at least comment what they mean somewhere.

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

#1


19  

I'd say both are correct, for different purposes:

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

If you're performing a simple go/no-go validation, e.g. is_numeric(), then true and false work nicely.

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

For something more elaborate, the 0==success paradigm is helpful in that it allows more than one error condition to be returned.

对于更复杂的东西,0 ==成功范例是有用的,因为它允许返回多个错误条件。

In this case, the caller can simply test against 0, or examine the non-0 returns for a more-specific explanation of the failure. e.g. a file open call can fail due to non-existence, insufficient permissions, etc.

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

#2


11  

The convention isn't exactly what you seem to think. Processes should exit with a 0 status to indicate success, and functions that return error codes will often use 0 to indicate "no error". But as a boolean, 0 should mean false and nonzero should mean true. To use 0 for boolean true will get you on The Daily WTF someday.

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

#3


6  

It's been a while since I programmed C, but I think you're talking about two different kinds of functions here:

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

  • is_foo is a functions that checks for some property foo and returns 0 (false) or non-0 (true) to indicate the boolean value of that property. When calling those functions no error state is expected (and if it happens, it's mapped on one of those values).
  • is_foo是一个检查某些属性foo并返回0(false)或非0(true)的函数,以指示该属性的布尔值。调用这些函数时,不会出现错误状态(如果发生错误状态,则会映射到其中一个值)。
  • foo is a function that executes the action foo. It returns 0 on success and a non-0 value on error.
  • foo是一个执行动作foo的函数。成功时返回0,错误时返回非0值。

#4


3  

I am not sure I agree that there is a convention of "returning zero from a function to indicate success."

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

AFAIK, the convention is that zero is false, and all nonzeros are true in the case of predicates.

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

However, this convention should only apply to obvious predicates that return booleans (e.g., true/false). If the primary goal of a function is not to return a boolean value (e.g., printf, fopen, etc.), then the return value is used to indicate failure reasons, and then you can adopt the UNIX convention of "silence or 0 unless there's a problem".

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

As for return values, there is nothing wrong with using fixed return values, it makes everything more convenient.

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

The big risk, IMHO, is that many people declare their own constants, and when others use the same files, you start running into conflicts with their own constants. So your TRUE/FALSE and conflict with somebody else's TRUE/FALSE down the line.

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

#5


3  

Especially when you name your function is_foo(), the standard C character functions (isdigit(), isupper(), etc) are a good precedent for doing it your way.

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

#6


3  

C has no concept of boolean other than 0 being false, and anything else being true.

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

The idea of returning 0 comes from having a return code indicating what the failure is. If you're not doing a return code, then there's nothing wrong with treating 1 and 0 as true and false. After all, TRUE and FALSE are just typedefs for 1 and 0 in C.

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

This should be well documented though, and your function comments should say explicity "Returns TRUE or FALSE".

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

You could also write if (is_invalid_foobar()), that could make the statement easy to understand and still semantically correct.

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

#7


2  

That's not so much a C convention as a UN*X shell one. Consider the Standard C iasalpha(), isdigit() etc functions. They all return non-zero to indicate success. Bottom line: in C 'true' is non-zero.

这不是一个C大会,而是UN * X shell。考虑标准C iasalpha(),isdigit()等函数。它们都返回非零值以表示成功。底线:在C中'真'不为零。

#8


0  

It's only bad if it burns you. If you never trace any bugs to this, I'd say you are OK. What's more important, is the comment above the function that starts with, "Returns zero for..."

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

The "nonzero is an error" convention is used when attempting to say why along with the error flag.

当试图说明为什么以及错误标志时,使用“非零是错误”约定。

#9


0  

to me, actually checking against 0 seems more natural and the compiler optimizes it anyway so i like to write for instance

对我来说,实际检查0似乎更自然,编译器无论如何都优化它,所以我喜欢写例如

if ( check_foo == 0 ) //do something

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

#10


0  

Return value by a function -- conventions for True and False OR Success and Error:

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

  1. An API etc. shows success with return value 0 and failure with return value = non zero error value.
  2. API等显示返回值0成功,失败返回值=非零错误值。
  3. If something is True; functions return 1. E.g. isStackEmpty() will return 1 if stack is empty.
  4. 如果某事是真的;函数返回1.例如如果stack为空,isStackEmpty()将返回1。

#11


0  

It's still completely arbitrary to return 1 or 0. Just be consistent and if there are error codes, at least comment what they mean somewhere.

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