1 = false and 0 = true? - c

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?

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).

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. :)

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?

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.

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.

Simple Answer
0 = false
1 = true

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.

Generally we think that 0 is false and 1 is true

Related

Wrong returned value in main function?

I previously read that 0 in C-Language refers to false while 1 is true.
And have noticed that the main function returns 0 but why is that? in case all of my code ran successfully it should return true (1).
Another related question, I still can't understand who can use the returnable value? since no other function called the main function inside my program so nothing can know if my program ran well or not.
I am a little bit confused.
Your logic would make sense if the return value of main were interpreted as a Boolean value, but it isn't. Returning from the initial call to main is like calling the exit function: It reports a termination status to the system you're running on.
Standard C specifies 3 portable exit statuses:
0, indicating success
EXIT_SUCCESS, also indicating success
EXIT_FAILURE, indicating failure
(The last two are macros defined in <stdlib.h>.)
On Unix, any 8-bit value (0 .. 255) is allowed. All non-zero values are interpreted as error codes. There is no universal convention for what any given number means, just that 0 represents success and anything else some kind of failure.
As for who can use the return value: On Unix, a parent process can use wait or waitpid to get the exit status of a terminated child.
In the C standard library, functions that perform an action generally don't return a true/false status. (Tests such as islower or isdigit do, but they don't have any other effects.) For example, remove (which deletes a file) returns 0 on success and -1 on error. This is also a common pattern with Unix system calls. For exmple, open returns a file descriptor (a non-negative integer) on success and -1 on error.
It's essentially what #Brandon already said in the comments.
main is supposed to return the exit/error code of the program. In the Unix convention, 0 is used to indicate no error (the error value is "false"). And then positive values are used for indicating that there is an error and what error it was.
It's really just about the kind of question you ask a program when it finish.
Case 1:
Did you fail?
Case 2:
Did you pass?
In the first case a "good program" will return false (aka zero)
In the second case a "good program" will return true (aka non-zero).
Consensus is to use Case 1, i.e. "Did you fail?". Therefore a non-failing program returns zero to say "I did not fail".
The benefit of this approach is that non-zero values can be used to expressed different kind of failures while zero is alway "no failure"
There's a difference between what the C language considers true (non-zero) or false (zero) and what value(s) the operating system uses to indicate a normal program termination.
To be strictly correct, C programs should exit with a code of either EXIT_SUCCESS for normal program termination or EXIT_FAILURE for abnormal termination. EXIT_SUCCESS will map to whatever code the underlying platform uses to indicate success, which may or may not be 0.

How to number my Custom errnos

I return a error code if my program was abnormally terminated (via exit()). For standard situations, I just return the underlying errno (for example, ENOMEM for failed mallocs etc). There are, however, also cases when I'll have to terminate due to my own reasons for which there are no system errnos defined.
What error values should I return so that they do not clash with the existing ones. Or am I doing the whole thing assbackwards?
edit: I am sorry if I was not clear with the question. I am not talking about enum etc (they are the mechanism for defining error codes). I was talking of the range of values they could take without clashing with the standard ones.
What I didn't know was that the program can only return 8 bit statuses. So it seems like #r is correct - that is a bit too small to accomodate maybe even all the standard ones, let alone my custom errors. so 1/0 it is :)
The width of the return code is usually pretty small, for example limited to 8 bits, so it's hard to store a lot of information in it. Really I wouldn't bother with exit codes besides 0/1 (success/failure) unless your program is intended for use in shell scripting, in which case you probably just need to figure out the error cases a potential shell script might need to check for and distinguish them (for example, "no match" versus "resource exhausted while searching").
What error values should I return so that they do not clash with the existing ones. Or am I doing the whole thing assbackwards?
Keep it simple. The most important test for error codes (that is also valid for plain functions) is what the caller can do about it. I have seen projects were people were introducing hundreds/thousands error code for all unique cases what in the end led to the total mess in the error handling (they were trying to give every function/SQL statement a unique exit code). And that - error handling - is precisely the party concerned with the exit codes.
My personal rule for return codes is to make sure that they are useful to the error handling. To exemplify, for a batch program I might have peeked the status codes like that:
0 - O.K.,
1 - internal but probably recoverable error (e.g. memory allocation error, kill other batches and try to restart),
2 - fatal error in config (restart will not help),
3 - fatal error in input data (replace input, try again),
4 - output got disk full error (clean /tmp, try again).
That is only an example to highlight that the error codes should be thought about from POV of the caller, not callee. If for example, full/partial automation isn't a target and users have to analyze log files anyway, then returning 0 or 1 would also suffice.
Have you considered using enum to define error codes?
Anyway, here is an interesting discussion about it.
There are few ways to do it.
1) Enums - This can be done in the following way. There is flexibility to add different error codes as and when you need and put them in a group. Say errors related to user authentication, file access, API errors etc.
enum
{
ERROR_GROUP_1 =100,// This gives 99 error codes for a particular group, can be initialised to negative value too.
GROUP1_1,
.
.
ERROR_GROUP_2 = 200
GROUP2_2,
.
.
and so on
};
2) Use pre-processor directives
#define ERROR_CODE_START 00000000L
#define ERROR_CODE_1 (ERROR_CODE_START + 1)
3) Negative return values as int but this will be lot of pain as the reference should be well documented for the values.
4) You can create a structure like GError. Pass a reference to this structure in every API and fill this. If its not NULL then the caller can check the error code and string which will be set in the API.
On a Posix compliant system, there is absolutely no point in returning any number outside the range 0 to 255. This is because the wait() system call only lets you have the bottom eight bits of the return value of your program (or possibly 16 bits).
In practice, you probably just want a handful of codes, maybe just 0 and 1. Further information can be communicated via stderr in a more useful (to a human) text format.

What is a good general approach for deciding return values in C?

My program is written in C for Linux, and has many functions with different patterns for return values:
1) one or two return n on success and -1 on failure.
2) some return 0 on success and -1 on failure.
3) some return 1 on success and 0 on failure (I generally spurn using a boolean type).
4) pointers return 0 on failure (I generally spurn using NULL).
My confusion arises over the first three -- functions that return pointers always return 0 on failure, that's easy.
The first option usually involves functions which return a length which may only be positive.
The second option, is usually involved with command line processing functions, but I'm unsure it has correctness, perhaps better values would be EXIT_SUCCESS and EXIT_FAILURE?
The third option is intended for functions which are convenient and natural to be called within conditions, and I usually emulate a boolean type here, by using int values 1 and 0.
Despite this all seeming reasonably sensible, I still find areas where this is not so clear or obvious as to which style to use when I create the function, or which style is in use when I wish to use it.
So how can I add clarity to my approach when deciding upon return types here?
So how can I add clarity to my approach when deciding upon return types here?
Pick one pattern per return type and stick with it, or you'll drive yourself crazy. Model your pattern on the conventions that have long been established for the platform:
If you are making lots of system calls, than any integer-returning function should return -1 on failure.
If you are not making system calls, you are free to follow the convention of the C control structures that nonzero means success and zero means failure. (I don't know why you dislike bool.)
If a function returns a pointer, failure should be indicated by returning NULL.
If a function returns a floating-point number, failure should be indicated by returning a NaN.
If a function returns a full range of signed and unsigned integers, you probably should not be coding success or failure in the return value.
Testing of return values is a bane to C programmers. If failure is rare and you can write a central handler, consider using an exception macro package that can indicate failures using longjmp.
Why don't you use the method used by the C standard library? Oh, wait...
Not an actual answer to your question, but some random comments you might find interesting:
it's normally obvious when to use case (1), but it gets ugly when unsigned types are involved - return (size_t)-1 still works, but it ain't pretty
if you're using C99, there's nothing wrong with using _Bool; imo, it's a lot cleaner than just using an int
I use return NULL instead of return 0 in pointer contexts (peronal preference), but I rarely check for it as I find it more natural to just treat the pointer as a boolean; a common case would look like this:
struct foo *foo = create_foo();
if(!foo) /* handle error */;
I try to avoid case (2); using EXIT_SUCCESS and EXIT_FAILURE might be feasible, but imo this approach only makes sense if there are more than two possible outcomes and you'll have to use an enum anyway
for more complicated programs, it might make sense to implement your own error handling scheme; there are some fairly advanced implementations using setjmp()/longjmp() around, but I prefer something errno-like with different variables for different types of errors
One condition I can think of where your above methodology can fail is a function that can return any value including -1, say a function to add two signed numbers.
In that case testing for -1 will surely be a bad idea.
In case something fails, I would better set a global error condition flag provided by the C standard in form of errno and use that to handle error.
Although, C++ standard library provides exceptions which takes off much hardwork for error handling.
For can't fail deterministic. Yes/no responses using a more specific (bool) return type can help maintain consistency. Going further for higher level interfaces one may want to think about returning or updating a systems specific messaging/result detail structure.
My preference for 0 to always be a success is based on the following ideas:
Zero enables some basic classing for organizing failures by negative vs positive values such as total failure vs conditioned success. I don't recommend this generally as it tends to be a bit too shallow to be useful and might lead to dangerous behaviorial assumptions.
When success is zero one can make a bunch of orthogonal calls and check for group success in a single condition later simply by comparing the return code of the group..
rc = 0;
rc += func1();
rc += func2();
rc += func3();
if (rc == 0)
success!
Most importantly zero from my experience seems to be a consistent indication of success when working with standard libraries and third-party systems.
So how can I add clarity to my approach when deciding upon return types here?
Just the fact that you're thinking about this goes a long way. If you come up with one or two rules - or even more if they make sense (you might need more than one rule - like you mention, you might want to handle returned pointers differently than other things) I think you'll be better off than many shops.
I personally like to have 0 returned to signal failure and non-zero to indicate success, but I don't have a strong need to hold to this. I can understand the philosophy that might want to reverse that sense so that you can return different reasons for the failure.
The most important thing is to have guidelines that get followed. Even nicer is to have guidelines that have a documented rationale (I believe that with rationales people are more likely to follow the guidelines). Like I said, just the fact that you're thinking about these things puts you ahead of many others.
That is a matter of preference, but what I have noticed is the inconsistency. Consider this using a pre C99 compiler
#define SUCCESS 1
#define ERROR 0
then any function that returns an int, return either one or the other to minimize confusion and stick to it religiously. Again, depending on, and taking into account of the development team, stick to their standard.
In pre C99 compilers, an int of zero is false, and anything greater than zero is to be true. That is dependant on what standard is your compiler, if it's C99, use the stdbool's _Bool type.
The big advantage of C is you can use your personal style, but where team effort is required, stick to the team's standard that is laid out and follow it religiously, even after you leave that job, another programmer will be thankful of you.
And keep consistent.
Hope this helps,
Best regards,
Tom.
Much of the C standard library uses the strategy to only return true (or 1) on success and false (or 0) on failure, and store the result in a passed in location. More specific error codes than "it failed" is stored in the special variable errno.
Something like this int add(int* result, int a, int b) which stores a+b in *result and returns 1 (or returns 0 and sets errno to a suitable value if e.g. a+b happens to be larger than maxint).

What should I return for errors in my functions in C?

Currently I'm returning -1 in my custom functions in C if something wrong happens and 0 for success. For instance, working with a linked list and some function needs a non-empty list to work properly. If the list passed as argument is empty, I return -1 (error) and 0 if it's not empty and the function worked without a problem.
Should I, maybe, return 1 instead of -1?
Is this the standard way of doing things in C or do you recommend a different approach?
Return a non-zero value to indicate failure. This way you can write you functions calls as so:
if(func_call())
{
doErrorHandling();
}
This convention will allow you to use any !0 value to indicate a specific error, and this will allow you to use one variable in a uniform fashion. So the body of the if shown in the example above can then have a switch statement to process the specific errors.
You can do it differently -- but if you choose to do so stick to a convention -- the win32 API (and other API's I have used) mix and match conventions unfortunately.
That sounds fine. -1 is used in I/O function because a positive return value usually means success and is the number of bytes that were processed. If you have multiple ways a function can go wrong, then you can either return different integers or set a global error variable (errno is used by the standard library) to contain the error code.
In terms of style, I prefer not to return status codes as it means my functions can't (cleanly) return anything else. Instead I would check the input before calling the function. But this is subjective and depends on the context.
I suggest that you find a way to format a fully-informative human-readable string at the point of the error, where all information is still available, and design a way to get it down thru the rest of the program, thru the user, his mobile phone, to your development team for the analysis.
This seems to me like an important feature of any design, if you want to produce better software faster. Killing error information on the way is a major crime, and C language is no excuse.
There are many schemes - but whatever you do, do it consistently!
If you don't have many failing conditions, just use 0 for error. That's because error tests are written in a simple way:
if (!list_insert(...)) { handle_error; }
Otherwise below-zero answers are good to use along with normal answers >= 0. You can use this for functions like list length, which in normal conditions will not be negative. Or if you want many error codes (-1 - nonexistant, -2 - not found, -3 ..., ...)

Why return a negative errno? (e.g. return -EIO)

Another simple example:
if (wpa_s->mlme.ssid_len == 0)
return -EINVAL;
Why the unary minus? Is this (usually) done for functions that return >0 on success and <(=)0 on failure, or is there some other reason?
First, this isn't really a C thing. You're looking at a function that is written in C for some purpose. The same conventions could be used in any language.
Back in my old Unix days, there was something of a convention that 0 meant success, a positive number meant minor problems, and a negative number meant some sort of failure. Therefore, there was also a sort of convention of if (foo() >= 0) { /* success of a sort */ }.
This was doubtless related to Unix process return codes, where 0 was success.
That's basically the reasons. Lots of functions have lots of "good" positive results, so that leaves the negative values for error codes.
C / POSIX error codes are a bit "historically grown," so there's not much sense in trying to attribute too much rhyme or reason to them.
Many more modern languages throw exceptions for errors so that they don't have to hijack part of their possible response range for error codes. Of course there are trade-offs either way.
Your understanding is broadly correct. The obvious interpretation is the right one.
The standard convention is slightly different than your formula, however.
In Unix, a program that exits with 0 status tests as true or success to CLI-level utilities like the shell. In the library, -1 is usually an error return.
This leads to a general paradigm where >= 0 means good and < 0 means error. None of this is set in stone.
BTW, this might be classified as the sentinel pattern and you could call it a sentinel return. It's actually a combination of a sentinel "value" and an error code, and it's easier to type and easier to make thread-safe than returning an error code in one place and a sentinel value for error in another.
Wikipedia reports that a sentinel value is used to terminate a loop, but I would think that a function return would be a far more common instance. No one is precisely in charge of these definitions.
From an optimization perspective, using negative numbers allows Unix-based kernels to check for an error code using only one comparison instead of two.
Functions in the kernel frequently return error codes in place of pointers. This means that the error codes can't overlap with valid pointer addresses, so they'd basically have to be either the lowest unsigned values (>= 0) or the highest ones (<= unsigned max).
Checking pointer values for NULL and for error codes are extremely common operations, so it makes sense to optimize them.
Typically the bottom values < 0x8000 are NULL and the top values are error codes (remember that -1 is stored as 0xff...ff, the maximum possible unsigned value).
This means that you can use one comparison to check for each:
NULL if x <= 0x8000 (true for 0 to 0x8000)
ERRNO if x >= (unsigned long)(-MAX_ERRNO) (true for -1 to -MAX_ERRNO)
You can see this happening in Linux's err.h file.

Resources