Any C compiler where "==" evaluates to larger than one? - c

As anything non-zero means true, but the >, <, == etc. operators returning 1 for true, I'm curious if there are any notable C compilers where these operators can result in a value greater than 1.
In other words, is there any compiler where int i = (a==b); would result in undefined behavior if I intended to use i not as a boolean value, but as an integer, and was assuming it would be either 0 or 1 ?

No, if there are, they're not C compilers :-) The standard mandates that relational and equality operators return 1 for true and 0 for false.
The rule for interpretation of integral values as boolean values by C states that 0 is false and any other value is true. See C11 sections dealing with if/while/do/for, which all contain language like "while the expression compares unequal to zero". Specifically:
6.8.4.1/2: In both forms [of the if statement, one with and one without an else clause], the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0.
6.8.5/4: An iteration statement [while, do and for] causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.
However, it's quite explicit what result you will get for the comparison-type expressions, you either get 0 or 1. The relevant bits of the C11 standard for these are all under 6.5 Expressions:
6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.
6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false.
6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0.
6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0.
6.5.3.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0.
And this behaviour goes way back to C99 and C89 (ANSI days). The C99 sections dealing with relational and equality operators also states that the return values is either 0 or 1.
And, while the C89 draft doesn't explicitly dictate the return values for equality operators, it does say:
The == (equal to) and the != (not equal to) operators are analogous to the relational operators except for their lower precedence.
And the relational operators section does state:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.
Reference: http://flash-gordon.me.uk/ansi.c.txt since I don't have any copies of the C89 standards floating around. I do have the second edition of K&R (the ANSI one from 1988) which basically says the same thing, in sections A7.9 and A7.10 of Appendix A, the Reference Manual. If you want a definitive answer from the first edition, that'll have to come from someone with a wife less prone to throwing out old junk.
Addendum:
According to Michael Burr, who is either not married or has a more accommodating wife than I in terms of keeping old books :-)
K&R 1st Edition (1978) also says the same in 7.6 and 7.7: "The [relational operators] all yield 0 if the specified relation is false and 1 if it is true." ... "The [equality operators] are exactly analogous to the relational operators except for their lower precedence."

They are guaranteed to return 0 or 1.
Reference:
C99 Standard: 6.5.9 Equality operators
Para 3:
The == (equal to) and != (not equal to) operators are analogous to the relational
operators except for their lower precedence.108) Each of the operators yields 1 if the
specified relation is true and 0 if it is false. The result has type int. For any pair of
operands, exactly one of the relations is true.

I don't think people here are answering the question. Question was not about what the standard says, the question was about if there are any notable compilers out there that do not obey the standard in that regard.
No, as far as I know, there are not.

I don't have access to the C standard, but according to Wikipedia:
C uses an integer type, where relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true and 0 if false, whereas the test parts of if, while, for, etc., treat any non-zero value as true.
Wikipedia luckily does have the correct citations, but as they're references to books, not sure how much help that is :).

As far as i can find is this from 6.5.9 paragraph 3 in C99 standard
The == (equal to) and != (not equal to) operators are analogous to the
relational operators except for their lower precedence.108) Each of
the operators yields 1 if the specified relation is true and 0 if it
is false. The result has type int. For any pair of operands, exactly
one of the relations is true.
Therefore it seems that the evaluated values should be either 1 or 0

By specification, to be considered the C language, the conditional operators must return 0 for false and 1 for true.
In haiku form:
Specification
Disallows this behavior,
Otherwise not C.

Before c89/c90/ANSI-C, the compare operators were guaranteed to produce a zero value on a "false" condition, and not-equal-to-zero otherwise. The substitute 1 for true "standardisation" that was introduced by c89 is seldomly needed, and in cases where is is needed, one could use a = (b==c) ? 1 : 0;.

Related

How "a<b<c" or "a>b>c" are evaluated in C

I found this question in many interviews and my teacher asked me the same the main doubt was that if I include <stdbool.h> in C99 standard will that evaluate this as (true)<c or (false)>c. Need a more clear answer than the linked post --> Usage of greater than, less than operators .
How a<b<c or a>b>c are evaluated in C
for example in the following code.
# include<stdbool.h>
int main(void){
int a = 1,b=2,c=3;
if(a<b<c)
printf("a great b great c");
}
thank you in advance.
From standard itself (Relational operators footnotes)
The expression a<b<c is not interpreted as in ordinary mathematics.
As the syntax indicates, it means (a<b)<c; in other words, if a
is less than b, compare 1 to c; otherwise, compare 0 to c.
Operator associativity dictates that a<b<c is equivalent to (a<b)<c (as opposed to a<(b<c)).
If a is less than b, a<b evaluates to 1. Otherwise, 0.
If the value returned by a<b (1 or 0) is less than c, the whole evaluates to 1. Otherwise, 0.
From the spec
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.) The result has type int.

Does the C standard explicitly indicate truth value as 0 or 1?

We know that any numbers that are not equal to 0 are viewed as true in C, so we can write:
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
However, I was wondering whether true / false are defined as 1/0 in C, so I tried the code below:
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
Does C standard explicitly indicate the truth values of true and false as 1 and 0 respectively?
Does the C standard explicitly indicate the truth values of true and false as 0 and 1 respectively?
The C standard defines true and false as macros in stdbool.h which expand to 1 and 0 respectively.
C11-§7.18:
The remaining three macros are suitable for use in #if preprocessing directives. They are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0 [...]
For the operators == and != , standard says
C11-§6.5.9/3:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
It is not explicitly indicated in C11. All language-level operations will return 1 as truthy (and accept any nonzero including NaN as true).
If you concern about _Bool, then true must be 1 because the standard only require it to hold 0 and 1. (§6.2.5/2).
Also in <stdbool.h> the macro true expands to 1 (§7.18/3)
==, !=, <, >, <= and >= return 0 or 1 (§6.5.8/6, §6.5.9/3).
!, && and || return 0 or 1 (§6.5.3.3/5, §6.5.13/3, §6.5.14/3)
defined expands to 0 or 1 (§6.10.1/1)
But all standard library functions e.g. islower just say "nonzero" for truthy (e.g. §7.4.1/1, §7.17.5.1/3, §7.30.2.1/1, §7.30.2.2.1/4).
§6.2.5/2: An object declared as type _Bool is large enough to store the values 0 and 1.
§6.5.5.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. …
§6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.107) …
§6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. …
§6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; …
§6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; …
§6.10.1/1: … it may contain unary operator expressions of the form — defined identifier — or — defined ( identifier ) — which evaluate to 1 if …
§7.4.1 (Character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.18/3: The remaining three macros are suitable for use in #if preprocessing directives. They are — true — which expands to the integer constant 1, …
§7.17.5.1/3: The atomic_is_lock_free generic function returns nonzero (true) if and only if the object’s operations are lock-free. …
§7.30.2.1 (Wide character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.30.2.2.1/4: The iswctype function returns nonzero (true) if and only if …
There are two areas of the standard you need to be aware with when dealing with Boolean values (by which I mean true/false values rather than the specific C bool/_Bool type) in C.
The first has to do with the result of expressions and can be found in various portions of C11 6.5 Expressions (relational and equality operators, for example) . The bottom line is that, whenever a Boolean value is generated by an expression, it ...
... yields 1 if the specified relation is true and 0 if it is false. The result has type int.
So, yes, the result of any Boolean-generating expression will be one for true, or zero for false. This matches what you will find in stdbool.h where the standard macros true and false are defined the same way.
Keep in mind however that, following the robustness principle of "be conservative in what you send, liberal in what you accept", the interpretation of integers in the Boolean context is somewhat more relaxed.
Again, from various parts of 6.5, you'll see language like:
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
From that (and other parts), it's obvious that zero is considered false and any other value is true.
As an aside, the language specifying what value are used for Boolean generation and interpretation also appear back in C99 and C89 so they've been around for quite some time. Even K&R (ANSI-C second edition and the first edition) specified that, with text segments such as:
Relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true, and 0 if false.
In the test part of if, while, for, etc, "true" just means "non-zero".
The && operator ... returns 1 if both its operands compare unequal to zero, 0 otherwise.
The || operator ... returns 1 if either its operands compare unequal to zero, and 0 otherwise.
The macros in stdbool.h appear back in C99 as well, but not in C89 or K&R since that header file did not exist at that point.
You are mixing up a lot of different things: control statements, operators and boolean types. Each have their own rules.
Control statements work like for example the if statement, C11 6.4.8.1:
In both forms, the first substatement is executed if the expression
compares unequal to 0.
while, for etc have the same rule. This has nothing to do with "true" or "false".
As for operators that are supposedly yielding a boolean result, they are actually yielding an int with value 1 or 0. For example the equality operators, C11 6.5.9:
Each of the operators yields 1 if the specified relation is true and 0
if it is false
All of the above is because C did not have a boolean type until the year 1999, and even when it did get one, the above rules weren't changed. So unlike most other programming languages where statements and operators yield a boolean type (like C++ and Java), they just yield an int, with a value zero or not zero. For example, sizeof(1==1) will give 4 in C but 1 in C++.
The actual boolean type in C is named _Bool and requires a modern compiler. The header stdbool.h defines macros bool, true and false, that expand to _Bool, 1 and 0 respectively (for compatibility with C++).
It is however considered good programming practice to treat control statements and operators as if they actually required/yielded a boolean type. Certain coding standards like MISRA-C recommend such practice. That is:
if(ptr == NULL) instead of if(ptr).
if((data & mask) != 0) instead of if(data & mask).
The aim of such style is to increase type safety with the aid of static analysis tools, which in turn reduces bugs. Arguably, this style is only meaningful if you do use static analysers. Though in some cases it leads to more readable, self-documenting code, for example
if(c == '\0')
Good, the intent is clear, the code is self-documenting.
versus
if(c)
Bad. Could mean anything, and we have to go look for the type of c to understand the code. Is it an integer, a pointer or a character?
I've programmed in many languages. I've seen true be 1 or -1 depending on the language. The logic behind true being 1 was that a bit was either a 0 or 1. The logic behind true being -1 was that the ! operator was a one's complement. It changed all the 1's to 0's and all the 0's to 1's in an int. So, for an int, !0 = -1 and !(-1) = 0. This has tripped me up enough that I don't compare something to be == true, but instead compare it to be != false. That way, my programming style works in every language. So my answer is to not worry about it, but program so that your code works correctly either way.
This answer needs to be looked at a bit more closely.
The actual definition in C++ is that anything not 0 is treated as true. Why is this relevant? Because C++ doesn't know what an integer is by how we think about it--we create that meaning, all it holds is the shell and rules for what that means. It knows what bits are though, that which make up an integer.
1 as an integer is loosely represented in bits, say an 8-bit signed int as 0000 0001. Many times what we see visually is a bit of a lie, -1 is a much more common way to represent it because of the signed nature of 'integer'. 1 really can't mean true proper, why? Because it's NOT operation is 1111 1110. That's a really major issue for a boolean. When we talk about a boolean, it's just 1 bit--it's really simple, 0 is false and 1 is true. All the logic operations hold as trivial. This is why '-1' should be designated as 'true' for integers (signed). 1111 1111 NOT'ed becomes 0000 0000---the logic holds and we're good. Unsigned ints is a little bit tricky and were a lot more commonly used in the past--where 1 means true because it's easy to imply the logic that 'anything not 0 is true'.
That's the explanation. I say the accepted answer here is wrong--there is no clear definition in the C/C++ definition. A boolean is a boolean, you can treat an integer as a boolean, but the fact the output is an integer says nothing about the operation actually being done is bitwise.
It happened because of the Relational Operators in your printf statement.
Operator == and operator !=
Since (0 == 0) holds true so, it gives a value 1
whereas, (0 != 0) doesn't hold true so, gives a value 0 .
I think I might have found the perfect solution to your problem.
Yes, 0 and any non-zero number are False and True respectively. Though there is no boolean data type in C.
But this is not the problem, the actual problem is how you are dealing with the modification of variable a in the your code :
int a = 16;
while (a--){
printf("%d\n", a);
}
When the compiler comes to the while (condition) statement, first the value of a is read by the compiler for the condition, then the arithmetic operation takes place, in this case,
a = a - 1 / a -= 1. So in the end there will be a case when a = 1 and the condition satisfies and after the arithmetic operation a-- which leads to a = 0, the print statement prints a as 0.
The above scenario depends on whether you use --a or a--. These two statements are read by the compiler in the order they are written.
For --a first the operation is performed on a then its value is read and vice-versa for the other.
So for case --a when a = 1 first the operation is done i.e a = a - 1 / a -= 1 and then a is evaluated for the condition, which then comes out to be Falsy as a = 0. Try the code below :
int a = 16;
while (--a){
printf("%d\n", a); // prints numbers from 15 to 1 as intended
}
OR deal with the modification of a inside the while loop block.
int a = 16;
while(a){
a = a - 1; // or a -= 1
printf("%d\n", a); // also prints numbers from 15 to 1 as intended
}

Expressions in c return 1 for true

In c programming ,all non zero numbers can be used in conditional expressions to return true. In that aspect why do expressions which evaluate to true return 1 ,not any other non zero value?
#include<stdio.h>
int main()
{
printf("%d",6==6);
}
output: 1
This is defined in the C standard:
6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
Similar for the other logical operators.
It makes a lot of sense to have a deterministic value for these cases, and the lowest positive non-zero value is a good candidate for that.
C11 draft
6.5.9 Equality operators
3
The == (equal to) and != (not equal to) operators are analogous to the
relational operators except for their lower precedence.108) Each of
the operators yields 1 if the specified relation is true and 0 if it
is false. The result has type int. For any pair of operands, exactly
one of the relations is true.
Because as you said, evaluating the both sides of that kind of expressions, the result could be true or false, that is a boolean value. By definition and convetion, in C standard, boolean values are represented with a 1 for true and 0 for false.

Can results of boolean operations be compared?

Does the C standard ensure that the boolean operations (==, !=, >, &&, ||, etc) always have the same value to represent truthfulness? In other words, do they always return some positive constant if true, or is the only guarantee that it will be a positive number?
The reason I'm asking this is to know if statements such as the one below are valid. That expression should be true if both pointers are NULL or both pointers point somewhere (not necessarily the same place).
if ((ptr1 == NULL) == (ptr2 == NULL))
Yes, although the rule for interpretation of integral values as boolean values by C states that 0 is false and any other value is true (a), the results of comparison operators is always 1 or 0.
So the expression (a == b) will never give you 42, for example.
The relevant bits of the standard (C11) are all under 6.5 Expressions:
6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.
6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false.
6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0.
6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0.
That covers all the ones you explicitly mentioned in your question. The only other boolean operation I can think of (off the top of my head) is the logical NOT operator ! which is also covered:
6.5.3.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0.
(a): See C11 sections dealing with if, while, do and for, which all contain language along the lines of something happen if/while "the expression compares unequal to zero". Specifically:
6.8.4.1/2: In both forms [of the if statement, one with and one without an else clause], the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0.
6.8.5/4: An iteration statement [while, do and for] causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.
Yes.
Values generated by operators will always be 1 for true and 0 for false.
The results of
negation operator (!)
relational operators (<, >, <=, >=)
equality operators (==, !=)
logical operators (&&,  ||)
is an int value of either 0 (false) or 1 (true).

Is the "true" result of >, <, !, &&, || or == defined?

When I for instance write 7>1 in C (say C99 if this is not an always-been feature), can I expect the result will be exactly 1 or just some non-zero value? Does this hold for all bool operators?
In C99 §6.5.8 Relational Operators, item 6 (<,>,<= and >=):
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false)
The result has type int.
As for equality operators, it's a bit further in §6.5.9 (== and !=):
The == (equal to) and != (not equal to) operators are analogous to the relational
operators except for their lower precedence) Each of the operators yields 1 if the
specified relation is true and 0 if it is false. The result has type int. For any pair of
operands, exactly one of the relations is true.
The logical AND and logical OR are yet a bit further in §6.5.13 (&&)
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
... and §6.5.14 (||)
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
And the semantics of the unary arithmetic operator ! are over at §6.5.3.3/4:
The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
Result type is int across the board, with 0 and 1 as possible values. (Unless I missed some.)
C follows Postel's Law for its boolean operators: be conservative in what you do, be liberal in what you accept from others. It will treat any non-zero value as true in boolean expressions, but it will always produce either a 0 or a 1 itself. 2 != 3 is always 1.
From the ISO C99 standard, section 6.5.8:
6 Each of the operators < (less than), > (greater than), <= (less than
or equal to), and >= (greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false. The result has
type int.
From section 6.5.9:
3 The == (equal to) and != (not equal to) operators are analogous to
the relational operators except for their lower precedence. Each
of the operators yields 1 if the specified relation is true and 0 if
it is false. The result has type int. For any pair of operands,
exactly one of the relations is true.
Same thing happens with the logical conjunction (&&) and disjunction (||) operators.
PS: Incidentally, this is why the bitwise operators (& and |) can usually be used as non-short-circuiting versions of the logical operators.
All C operators that yield logically true/false values always yield a result of type int with the value 0 for false, 1 for true.
That's not the case for all C expressions that yield logically true/false values. For example, the is*() character classification functions declared in <ctype.h> (isdigit(), isupper(), etc.) return 0 if the condition is false, but may return any non-zero value if the condition is true.
As long as you use the result directly as a condition:
if (isdigit(c)) ...
if (!isdigit(c)) ...
if (isdigit(c) || islower(c)) ...
and don't attempt to compare it to something:
if (isdigit(c) == 1) ... /* WRONG */
if (isdigit(c) == true) ... /* ALSO WRONG */
this shouldn't cause any problems.
(You can safely compare the result to 0 or false, but there's no good reason to do so; that's what the ! operator is for.)

Resources