34

I came across an is_equals() function in a C API at work that returned 1 for non-equal SQL tables (false) and 0 for equal ones (true). I only realized it after running test cases on my code, one for the positive example and one for the negative and they both failed which at first made little sense. The code in the API does not have a bug as the output was recorded correctly in its documentation.

My questions – are there upside down worlds / parallel universes / coding languages where this logical NOTing is normal? Isn't 1 usually true? Is the coder of the API making an error?

user3840170
  • 26,597
  • 4
  • 30
  • 62
Ben
  • 2,430
  • 3
  • 22
  • 24
  • 1
    I don't really understand your question.. – user541686 Jun 25 '11 at 01:28
  • Sometimes 0 indicates success and other numbers specify error codes. But I understand why this is confusing since the function returns true/false. – Marlon Jun 25 '11 at 01:56
  • 35
    0=false, 1=true, and everything else = true (For anyone looking for a quick answer to the question in the _title_). Source: [§ 4.12](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf) – Gima Apr 07 '14 at 09:08
  • 1
    Only only look as far as something like strcmp (string compare) in the C standard library to see an example where a general "1 = true" assertion doesn't make sense. – NoelC Aug 31 '15 at 14:39
  • > Is the coder of the API making an error? No. – dud3 Oct 19 '16 at 12:42
  • Actually it really depends on a language, there's no such a thing that says: 1 has to be true and 0 has to be false. In languages such as js, `-1, 1, 'string'` and I don't know what else is considered true, on the other hand, `0, undefined, null, NaN, 'empty string'` is considered false. – dud3 Oct 19 '16 at 12:54

8 Answers8

52

It is common for comparison functions to return 0 on "equals", so that they can also return a negative number for "less than" and a positive number for "greater than". strcmp() and memcmp() work like this.

It is, however, idiomatic for zero to be false and nonzero to be true, because this is how the C flow control and logical boolean operators work. So it might be that the return values chosen for this function are fine, but it is the function's name that is in error (it should really just be called compare() or similar).

caf
  • 233,326
  • 40
  • 323
  • 462
  • Interesting. For this to be the case then there would be two inconsistencies. 1) The is_equals() function should really be called compare(). 2) The function would need to return a negative number. Currently it only returns 0 and 1. Perhaps a previous revision did. Then the question is are 1&2 more likely then the programmer stupidly messing up "C flow control." Perhaps the former since the rest of the functions in the API conventionally return 1 for true and 0 for false. – Ben Jun 25 '11 at 04:27
  • 1
    Many int typed C functions do return 0 when it is a successful result, but that shouldn't be seen as a **false** result, but rather **false** _error code_. There is a logic to it. It is more internally consistent than it might appear. Though, I don't know if seeing it as "error is false" is the intended mental model they were going for, or just how I'm interpreting it... – Chris L Sep 19 '13 at 13:54
  • I have encountered many variants, particularly in Pascal code. Things like -1 false 0 true or -1/1 – Martien de Jong Sep 23 '20 at 12:35
16

This upside-down-world is common with process error returns. The shell variable $? reports the return value of the previous program to execute from the shell, so it is easy to tell if a program succeeds or fails:

$ false ; echo $?
1
$ true ; echo $?
0

This was chosen because there is a single case where a program succeeds but there could be dozens of reasons why a program fails -- by allowing there to be many different failure error codes, a program can determine why another program failed without having to parse output.

A concrete example is the aa-status program supplied with the AppArmor mandatory access control tool:

   Upon exiting, aa-status will set its return value to the
   following values:

   0   if apparmor is enabled and policy is loaded.

   1   if apparmor is not enabled/loaded.

   2   if apparmor is enabled but no policy is loaded.

   3   if the apparmor control files aren't available under
       /sys/kernel/security/.

   4   if the user running the script doesn't have enough
       privileges to read the apparmor control files.

(I'm sure there are more widely-spread programs with this behavior, but I know this one well. :)

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • 2
    `grep` is a good one. “Normally, exit status is 0 if selected lines are found and 1 otherwise. But the exit status is 2 if an error occurred.” – Josh Lee Jun 25 '11 at 01:35
  • Thanks, that makes sense. I didn't realize error statuses worked that way. The is_equals case is still weird because it's not associated with any sort of error checking. – Ben Jun 25 '11 at 01:38
  • 1
    "there is a single case where a program succeeds but there could be dozens of reasons why a program fails" – also known as the [Anna Karenina principle](https://en.wikipedia.org/wiki/Anna_Karenina_principle) :) – unhammer Dec 05 '17 at 07:52
  • @unhammer, hehe, that's great! Thanks – sarnold Dec 06 '17 at 04:31
7

Simple Answer

0 = false 
1 = true
Abdul Basit Rishi
  • 2,268
  • 24
  • 30
6

I suspect it's just following the Linux / Unix standard for returning 0 on success.

Does it really say "1" is false and "0" is true?

Community
  • 1
  • 1
Peter K.
  • 8,028
  • 4
  • 48
  • 73
  • Seems like it, but, that'd be a pretty brain-dead application of the standard. `IsWhatever` is obliged to return 0 if it is not `Is`, otherwise, how are you going to say `if(!IsWhatever()){}`? – GSerg Jun 25 '11 at 01:33
  • To clarify - it says returns 0 if equal, 1 if not equal. Since it's an is_equals function, I took the two as synonymous. – Ben Jun 25 '11 at 01:34
6

There's no good reason for 1 to be true and 0 to be false; that's just the way things have always been notated. So from a logical perspective, the function in your API isn't "wrong", per se.

That said, it's normally not advisable to work against the idioms of whatever language or framework you're using without a damn good reason to do so, so whoever wrote this function was probably pretty bone-headed, assuming it's not simply a bug.

Brennan Vincent
  • 10,736
  • 9
  • 32
  • 54
  • 4
    0+1=1, FALSE or TRUE is TRUE; 0*1=0, FALSE and TRUE is FALSE; etc is the reason for the notation. – jinawee Aug 22 '19 at 12:42
6

It may very well be a mistake on the original author, however the notion that 1 is true and 0 is false is not a universal concept. In shell scripting 0 is returned for success, and any other number for failure. In other languages such as Ruby, only nil and false are considered false, and any other value is considered true, so in Ruby both 1 and 0 would be considered true.

Kelend
  • 1,417
  • 2
  • 11
  • 18
  • 1
    Success and failure (error codes) is a very different concept from boolean values. Also, it's only logical for a language that supports boolean types to evaluate valid expressions as true, hence 0 equals true (0 is a valid integer value). – Spidey Apr 30 '12 at 19:59
2

I'm not sure if I'm answering the question right, but here's a familiar example:

The return type of GetLastError() in Windows is nonzero if there was an error, or zero otherwise. The reverse is usually true of the return value of the function you called.

user541686
  • 205,094
  • 128
  • 528
  • 886
0

Generally we think that 0 is false and 1 is true

  • This answer does not seem to contain any information that other answers do not already have – user16217248 Sep 24 '22 at 19:14
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/32760141) – abdo Salm Sep 27 '22 at 01:39