last day (15 days later) » 

10:24
4
Q: why are the definition of true and false in stdbool.h the exact opposite from the UNIX programs true and false?

toogleystdbool.h is usually defined as: #define false 0 #define true 1 (Sources: OpenBSD, musl, etc.) whereas the unix program false - which just has a unsuccessful status code, is defined as: int main(int argc, char *argv[]) { return (1); } for completeness, the definition of the unix progra...

A very stupid suggestion (on my part) but maybe false(1) is returning 1 because it is interpreting the following: is it false? -> yes -> 1 instead of print 0 if false?
I wonder if there are any actual historical references on that available. For all practical purposes, it's "because it's always been like that", and of course one could make guesses as to why. I've made mine in an answer here: unix.stackexchange.com/a/632683/170373
Then i think my question is additionally: why do many C programs/functions return 0, which is false according to stdbool..h, altough no error occured? i mean the inconsistency is what annoys me.
You're confusing boolean logic with exit statuses of processes. They have very little to do with each other.
@Kusalananda, well except for the fact that they treat the truthiness of integers in exactly the opposite way, which seems to be precisely what they're asking about.
10:24
@ilkkachu yes, exactly.
@ilkkachu I understand why you bring integers into the question, but it's only confusing. A C program returns EXIT_SUCCESS to signal success, and EXIT_FAILURE otherwise. What these values are does not matter, only that when used in a test, EXIT_SUCCESS behaves like "true". The actual values of the bool constants true and false similarly does not matter, as true behaves like a "true" value when used in a test. You can use false in the shell in a test and it will behave "falsy", that's all that matters.
@Kusalananda, hmm. On the contrary, it seems to me it's exactly the point. For boolean logic, you just need "true" and "false", no need to think about their numerical values, just like you said. When working with the logic on that level, it works the same in C and in the shell. No difference, no question. But since it's not just those two, and instead integers also have truthiness, we need some mapping. Up to an extent, the choice is arbitrary, but it's somewhat curious that C and the shell use exactly the opposite customs, even though there's some shared history between Unix and C.
@ilkkachu Back to my initial point: The exit status is a different thing from the bool constants in C (unless you use them in tests, in which case they work identically, as in my previous comment). The C library also have a set of non-zero errno numbers, and it's common practice to return a non-zero status value from a function upon failure, just as in the shell. So C and Unix (the shell) go hand in hand in this manner. When you start to compare exit statuses, or function return values, then you get boolean values.
The exit statuses are a different thing, and their numerical values are treated differently. And it seems the "why" on that is exactly the question here. Yes, it's also common in C to return 0 (or NULL == 0) on failure, probably because there's need for more than error return, but only one success return. And that's fine. But that doesn't tell why zero is truthy in one, and falsy in another. Obviously the "one success, many errors" works in both cases.
Now, a potential reason for treating zero == success as truthy would be that it allows useful logic mkdir foo && mv file foo and at the same time allows more than one error return value. Then, presumably there's some other reason to treat it the other way in C. Also, it's not like the truth values would only come up with an explicit comparison, an if statement in both shell and C implicitly compares against zero. The sense of the comparison is just different. (int x=123; if(x) { ...} is valid, as is if (exit 123); then ...)
A nitpick. Technically there are no bool constants in ISO C. There is a _Bool type which is "large enough to store the values 0 and 1." bool is a macro which expands to _Bool. true and false are also macros which expand to 1 and 0 also. And, "notwithstanding the provisions of 7.1.3, a program may undefine and perhaps then redefine the macros bool, true, and false."
10:24
@fpmurphy, yes, and when ever C needs anything that can be reasonably thought of as a truth value, it just says that the value is compared against zero. Which is why it doesn't seem to make sense to imply that one would have boolean values any more, or less, than the other.
@Barmar, if they're looking for actual historical references, then it doesn't really answer it. I thought about slapping a bounty on this in the hope of someone finding better references, but what with the s**tstorm this ended up, maybe closing it wouldn't be that bad a result either...
@Kusalananda "You're confusing boolean logic with exit statuses of processes." But the shell has numerous constructs that perform boolean logic using th exit status. It has if and while statements that test it, and !, && and || operators that process it as a boolean.
@Barmar The shell's constructs that acts on exit-statuses acts on exit-statuses, not on booleans. Try if 1; then echo ok; fi. The difference between most programming languages and the shell is not in the treatment of booleans but the fact that the statements that traditionally acts on booleans actually act on exit-statuses. The if statement, or the && operator, do not act on a boolean. They act on an exit-status. Since an exit-status is not a boolean, confusing the two leads you to believe that "booleans in the shell are inverted". They are not, since they are not booleans.
@Kusalananda If it walks like a duck and quacks like a duck, it's a duck. All these operations obey standard boolean algebra axioms, that makes them booleans.
10:24
@Barmar An exit-status is not a boolean until you compare it to zero. The result of that comparison is a boolean. The if statement (etc.) makes that comparison, and does not use the exit-status as a boolean directly.
@Kusalananda It seems like we have different understandings of what "boolean" means. A boolean is a logical value. You do if some_command; and if tests the exit status for its truthiness.
@Barmar No, we agree on that what you just wrote there. We don't agree that the exit-status is a boolean or not. You seem to think that exit-statuses are booleans. I do not.
@Kusalananda It's really a much simpler question: In most programming languages, 0 is the falsey value, but in shell exit status 0 is the truthy value. Why this difference?
@Barmar Again, an exit-status is not a boolean. A boolean can not hold only two states, true and false. An exit-status can hold values from 0 to 127. They are not the same. You compare an exit-status to zero to get a boolean.
@Barmar You can see an exit-status as an index into a table of failure-reasons. One of these conditions, 0, is "no failure". What do you do to see whether your program failed or not failed? You check whether your exit-status corresponds to the "no failure" condition. This test results in a boolean value of true or false. Before the test, you just had an exit-status. These two integers are two different things.
Fun facts: Bash's manual says that ! expression is "True if expression is false". (Similarly for && and ||.) And the short POSIX description for true says "return true value". (similarly for false)
10:24
@Kusalananda Should this looong (side) discussion be moved to chat?

last day (15 days later) »