Question about C ! operator - c

My understanding of this is as follows. In C, the ! operator returns 0 if it is given a nonzero value and returns a nonzero value if it is given 0.
Say you have this little snippet of C code:
int y = 0;
int z = !y;
What value will go into z? Does it simply take !0 to be 1? Is it system dependent? Does the C standard dictate what is supposed to happen? I ran into these questions while doing some homework earlier tonight dealing with bitwise 2's-complement integer manipulation. I got a certain problem to work, but I'm sort of scratching my head as to why it works. Thanks a lot for any info!

Truth values "generated by" C are always 0 or 1.
It is true (heh) that a non-zero expression is generally considered "true" in if and so on, but when the language itself needs to generate a truth value it uses 0 for false and 1 for true.
Since the ! operator is a logical operator, it will always result in 0 or 1.
So in your case, z will be set to 1.
Update: See this FAQ entry for more discussion, that's what I had in mind with the "generated by" wording. Amazingly, it even has the same pun (I did not look this entry up before writing my answer). Not sure if this is an indication of me having a good sense of humor, or not.

The result of an unary-expression with the ! operator is an int with value 0 or 1.

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).
From The C Standard (n1124) section 6.5.3.3.

Related

Why does the logical statement !0x00 return 0x01 in C?

I'm reading Computer Systems a programmers perspective, and I'm getting into logical operators, which are similar to bitwise operators, but with a few differences.
What I CANNOT figure out is that when you have a logical operand !0x00 returns 0x01 rather than 0x11?
! is NOT, right? So NOT 0(false) should be 1(true) and another NOT 0(false) should also be 1(true) as well, right?
I look at the bitwise operator example : ~00, naturally that would return 11, but C's logical operators seem to work with vast differences.
Why does this happen?
What I have tried already: Reading a little further to find the answer I seek, it doesn't seem to be here.
What I think the problem is: Might have something to do with how Hexadecimals work? But, Hexadecimals can still have 0x11. . . .
Because that's how the language is defined. ! is the logical NOT operator and boolean logic in C works on 1 and 0, representing true and false.
C17 6.5.3.3:
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.
You can think of it as if returning bool, though it actually returns int for backwards-compatibility reasons. Unlike C++ where it does return bool. The same goes for relational and equality operators.
The expression !n is equivalent to (n==0). It returns 1 if true, 0 if false.
Neither !0x00 nor ~0x00 will give you 0x11.
!n is the same as n==0 and evaluates to 1 or 0.
~n negates the bits of the binary representation, not the digits of the literal you chose to enter the number.

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
}

Using Exclamation Marks '!' in C

I have come across a problem involving exclamation marks and integers whilst reading a code in my reference book.
Let us say I have declared an integer variable named number - int number = 0;
I then use a while function involving an exclamation mark and number
while(!number)
{
...
}
I am confused with this because I do not know what does !number mean and what would be possible returned results? I am not sure if this can be used, but as I said, I saw it in my book.
Therefore, it would be great if someone could tell me what does !number mean and what does it evaluate?
Thank you in advance.
We can treat ! as not.
So if a number is non-zero (either positive or negative) it returns Zero.
If it is zero, it returns 1.
int i = 13;
printf("i = %d, !i = %d\n", i, !i);
printf("!0 = %d\n", !(0));
In C, !number will evaluate to 1 if number == 0 and to 0 if number != 0. And in C, 1 is true and 0 is false.
Using an explicit comparison like number == 0 have the same effect but you might find it easier to read.
It's a negation or "not" operator. In practice !number means "true if number == 0, false otherwise." Google "unary operators" to learn more.
It is used for Negation of a number.It is a Unary Operator.
For Example:-
If we are using it with zero :- !0 then it will become 1
with one !1 = 0
The negation operator (!) simply just reverses the meaning of its operand.
The operand or the expression must be of arithmetic or pointer type. But the operand/result of expression is implicitly converted to data type bool (boolean 0 means false, Non zero means True).
The result is true if the converted operand is false; the result is false if the converted operand is true. The result is of type bool.
so
while(!number)
{
...
}
since variable number is 0 , while(!number) ie, !0 which is 'negation of 0' which is 'TRUE' then it code enters the while loop()

double negation in C : is it guaranteed to return 0/1?

Is !!(x) guaranteed by the standard to return 0/1?
Note that I am not asking about c++, where a bool type is defined.
Yes, in C99, see §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).
So !x and !!y can only yield 0 or 1, as ints.
For other operators, in C99, see also Is the "true" result of >, <, !, &&, || or == defined?
This is a comment really, but it's too long.
I found a very bizarre document while looking for the standard to answer your question: The New C Standard: An Economic and Cultural Commentary. And they say academia is under-funded. (Here is the full, 2083 page 10.5MB PDF. The former link is just the section on double negation.)
It has this to say on the subject of double negation:
A double negative is very often interpreted as a positive statement in English (e.g., “It is not unknown for double negatives to occur in C source”). The same semantics that apply in C. However, in some languages (e.g., Spanish) a double negative is interpreted as making the statement more negative (this usage does occur in casual English speech, e.g., “you haven’t seen nothing yet”, but it is rare and frowned on socially1).
I believe that the author would be happy knowing that this is of no use whatsoever in answering your real question (the answer to which is yes.)

C: What will the statement 'return A || 1' return when A >1?

Although I wouldn't have written it myself, what is the expected result of the following statement where A (guaranteed to zero or positive integer) is greater than 1?
return A || 1;
In many languages, I would expect A to be returned, unless the value of A is zero, in which case 1 would be.
I don't have my C book to hand, but I note that in reality, the value 1 always seems to be returned. Is this a result of compiler optimisation or given the potential ambiguity of the expression, is it that the return value is non-deterministic?
The standard says
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
See section 6.5.14 of the standard.
The expected result is YES (or true)
|| operator returns true value if at least one of its operands is true (2nd operand in your code is obviously true)
This is straight C (no Objective-C involved). It will always return 1.
In C, the result of ||, &&, or ! is always 0 or 1, never any other non-zero value, regardless of the values of the operands. That means your A || 1 will always yield 1.
with C-based languages any nonzero value is true(represented by 1). And if your A is zero it will check the other comparisons if it's an OR comparison
Suffice to say, in your example, whatever the value of A is, will always return 1 even if you are using || 2. with 2 being nonzero, when performed with logical operator OR, will always return true(represented by 1)
I believe that the compiler will optimize and not even examine the value of A. Can someone confirm? I was under the impression that with A&&0, A||1, and A||0 (=A&&1), the compiler saves time by recognizing that the expression can be simplified to 0, 1, or A respectively.

Resources