[It seems odd this doesn't exist, so apologies in advance if it's a duplicate]
I want to test for logical equality in C. In other words, I want to know whether two values would be equal if both were converted in the normal way associated with logical expressions.
In C99, I think that
(bool)a == (bool)b
gives what I want. Is that correct? What is the normal way of writing this in traditional C?
You typically see this:
if ((a == 0) == (b == 0))
Or
if (!!a == !!b)
Since !!a evaluates to 1 if a is nonzero and 0 otherwise.
Hope this helps!
In C, zero is false. If you want to convert any value to its boolean equivalent, the standard way (well, except that there's almost never a need for it) is to prefix an expression with !! , as in !!a. In the case of your expression,
!!a == !!b
may be simplified to
!a == !b
In pre-C99 C, the tradiitional, idiomatic way to "cast to bool" is with !!.
There is no (bool) in traditional c. True/False is handled using ints. You can check for boolean equality with
a ? b : !b
Related
I am a getting warning:
warning: '<<' in boolean context, did you mean '<' ? [-Wint-in-bool-context]
for the code similar to the following:
int a=7,b=3;
int index=((a<<1)||b)&&5;
To explain the rationale behind such warnings:
C did get a boolean type _Bool/bool as per C99, but no changes were done to the behavior of the various logical operators of the language. That is:
Equality operators ==/!=
Relational operators <,<=,>,>=
Logical AND &&
Logical OR ||
Logical negation !.
Despite C having a boolean type, all of these operators return type int with value 1 or 0. Unlike C++ where all of these operators actually return type bool with value true/false. This is a known flaw of C.
It's common good practice however to treat such expressions as if they were boolean. Coding guidelines like MISRA C encourage the use of a fictional type "essentially boolean", meaning any expression that could be treated as _Bool. The reason for this is that it makes code more self-documenting and also makes it harder to create various typo-related bugs.
For example if(str) could mean check for NULL, or it could mean check for null termination but oops we forgot to dereference. Same thing with if(*str). Whereas if we only pass the result of a logical operator to if, the code becomes much clearer and it becomes harders to write bugs: if(str != NULL) could only mean check for NULL and if(*str != '\0') could only mean check for null termination.
In your case, the || operator only cares if the operands are zero or non-zero ("essentially boolean"). In case a is non-zero then a<<1 will not change that. In case a is zero, then a<<1 is zero as well. Since the result is passed on to a logical operator, "in a boolean context", the shift is pointless - hence the warning. But of course a<<1 might take all kinds of other values in another context such as for example if(a<<1 & mask).
It would be reasonable to strongly suspect that you actually meant to write a<1 instead. Because that would yield either 0 or 1, where < is also a logical operator like ||.
I got the solution. We should avoid integers using with logical operators (eg. ||,&&). Using integers with bitwise operators (eg. <<,&,|,etc.) is fine.
Sometimes we don't get this problem while running on compilers because of low priority warning filters. In complex and warning sensitive compilers it comes up.
Thanks
#include<stdio.h>
void main()
{int a=12,b=7;
if(!a>=20) //this is the part can't identify
b>>1;
printf("b=%d",b);}
What does mean If(!a>=20) in C this programme?
The expression !a >= 20 is the same as (!a) >= 20.
And ! is the logical-not operator. If a is "true" (which all non-zero values are) then !a will be false.
And false is implicitly convertible to the int value 0 (and true to 1).
So what the expression is doing is checking if a is "true" or "false" and compare the 0 or 1 result of that with the integer value 20. And as both 0 and 1 are smaller than 20 the condition will be false.
Is this a interview question?
Or some tricky problem?
This c - code is not proffesionally indentend and missing of bracketing.
This is unusual way because if statement will never happend and in addition the code inside 'if' does nothing...
As mentioned above !a - will return integer - 0 for non-zeros values of 'a', and integer - 1 for zero value of 'a'...
b>>1 do a bit shifts, but result is not storing anywhere...
I guess that the proper form of code should looks like:
#include<stdio.h>
void main()
{
int a = 12,b = 7;
if(!(a >= 20))
b = b >> 1; // it will execute and produce b equal to 3
printf("b=%d", b);
}
It means the author was aiming for a convoluted form of if (a < 20) but missed.
The unary ! operator has higher precedence than >=, so the expression is parsed as (!a) >= 20. The result of !a is 0 if a is non-zero and 1 if a is zero, neither of which are greater than or equal to 20, so this expression will never be true regardless of the value of a.
It’s pretty clear the author meant to write !(a >= 20), which as I said earlier is the same as a < 20.
To understand any expression, there are sort of two ways of doing it.
For a sensible expression, that matches common idioms, that is well-balanced with the ways people speak and think, you can just sort of look at it and know what it does. If you see the expression
if(a >= 20)
then even if you don't know anything about C programming, as long as you know that > is "greater than", you can read this as "if a is greater than or equal to 20" and get a pretty good (and accurate!) idea of what it does.
But for a more complicated expression, that doesn't match a pattern you've seen before, and especially if it's badly written (or even deliberately confusingly written), you have to analyze it strictly logically, breaking it up into smaller parts, using the same rules the compiler will use. For an expression like this, the important rules have to do with precedence.
We've got
! a >= 20
Hopefully you know that ! is the logical negation operator: it turns false to true, and true to false.
So we're doing something with the variable a here, and we're negating something, and we're comparing something to see if it's greater than or equal, and we're comparing to 20. But how do these pieces fit together, exactly? Which parts of the expression are combined with which other parts?
Here there are really only two possibilities. We could be comparing a to see if it's greater than or equal to 20, and then negating the result. Or, we could be negating a, and comparing the negation of a to see if it's greater than or equal to 20.
To understand these various situations precisely, we can use some special notations to remove all ambiguity. To clearly express the notion of "comparing a to see if it's greater than or equal to 20, and then negating the result" we could write it using explicit parentheses:
! (a >= 20 )
or we could draw a "parse tree", showing graphically how the pieces fit together:
!
|
>=
/ \
a 20
Similarly, to clearly express the notion of "negating a, and comparing the negation to see if it's greater than or equal to 20" we could write it using explicit parentheses:
( ! a ) >= 20
or we could draw a different parse tree:
>=
/ \
! 20
|
a
But we still haven't answered the original question: for the "bare" expression
!a >= 20
which of these two interpretations holds? As I said, to answer it we need to look at the precedence of the operators. The C precedence table says that ! has higher precedence than >=. This means that ! "binds more tightly" than >=. So ! applies to a, and then >= applies to the result. This means that the interpretation we get is as if we had explicitly written
( ! a ) >= 20
So this means, "first logically negate 20". Now, in C, anything with the value 0 is "false", and anything with a nonzero value is "true". We know that a is 12, so that's "true". So !a is false, or 0.
Now we can compare to 20. Is 0 greater than or equal to 20? No, it is not. So the condition
if(!a >= 20)
will not do the controlled thing.
That answers your main question, but there are a few other things which it might be interesting to look at.
First, what is "the controlled thing"? You had
if(!a>=20)
b>>1;
which is kind of hard to read. Normally, when we write an if statement, we indent the controlled thing, to make it more obvious that it is, well, the controlled thing. So let's first write it as
if(!a >= 20)
b >> 1;
So now it's more clear that, if the condition is true, we'll do b >> 1. But we've determined that the condition is not true, So we're not going to do this thing.
What's odd is that even if we did do this thing, it wouldn't do anything. The expression
b >> 1
means, "take b's value and shift it to the right by 1 bit position". Okay, so we do that, but then: what do we do with the shifted result? Nothing! It disappears! This is like saying
b + 1;
Generally, you compute a new result, like b >> 1 or b + 1, so that you can do something with it, like print it out, or assign it to a new variable.
It would have made more sense if the code were written
if(!a >= 20)
b >>= 1;
or
if(!a >= 20)
b = b >> 1;
Now, in either case, we've got code that will, maybe, take b's value, shift it right by one bit, and store the modified value back in b.
But there's still the puzzle that the condition is always false, meaning that we never do the thing.
We decided that the expression
!a >= 20
meant "take a's logically negated value, and see if it's greater than or equal to 20." But logical negation is a "Boolean" operation, that only ever yields true or false. So, no matter what a's value is, the expression !a is always going to be either true or false. So it's always going to be either 1 or 0. So it's never going to be greater than (or equal to) 20.
And actually, things are doubly strange here, because most of the time, if you look at the whole class of true/false Boolean expressions, and the whole class of numeric expressions involving integer and floating-point values, these two classes are sort of like oil and water, they don't mix. You can take an integer and a Boolean value and add them together, or ask if one is greater than or equal to another, but its a strange thing to do, it's suspect, it doesn't usually make sense.
So this is a very strange, basically very stupid, expression to write, because it never does anything interesting. A more interesting expression would be
if(!(a >= 20))
Now, we're comparing a's value (which is a number) to 20. Then, we're taking the true-or-false result, that we got from comparing a to 20, and logically negating it, changing true to false or false to true. That's a much more sensible thing to do.
But in the end, even though it makes more sense, a condition like
if(!(a >= 20))
is still a little bit more complicated, a little bit more confusing, a little bit harder to read than it probably has to be. Instead of saying, "if it's not the case that a is greater than or equal to 20", why not just say, "if it is the case that a is less than 20"? That is, it would be 100% equivalent, and probably much less confusing, to just say
if(a < 20)
I had the need to code a statement of the form
a = a || expr;
where expr should be evaluated and the result be assigned to a iff a is not set. this relies on the logical OR's short-circuiting capabilities.
The shorter way to write the above would, of course, be
a ||= expr;
but (to my surprise) C does not have logical assignment operators.
So my question is twofold. First, is there a shorter way to write the first statement in standard C (the ternary operator is even worse - a = a ? a : expr requires me to spell out a thrice).
Secondly, why aren't there logical assignments in C? The possible reasons I could think of are:
it makes the grammar harder to parse?
there is some subtlety in handling short-circuiting for these cases?
it was considered superfluous (but isn't that an argument against ALL the operator assignments?)
EDIT
Please unlock this question because:
The question it has been linked to (as a alleged duplicate of) HAS NOT BEEN ANSWERED. The (accepted) answer to that question states that ||= is not present because duplicates the functionality of |=. That is the wrong answer. |= does not short-circuit.
C and C++ are NOT the same languages. I wish to know why C doesn't have it. In fact, the fact that derived languages like C++ and, particularly, Java (which did not suffer from the problems of legacy code as has been suggested in Edmund's answer) makes the question even more interesting.
EDIT 2
It now seems like my original intent was wrong. In the statement a = a || expr (where a is integral and expr returns an integral value, first both a and expr will be implicitly converted to "booleans", and then the "boolean" value will be assigned to a. This will be incorrect — the integral value will be lost. Thanks, Jens and Edmund.
So for the first part of the question, the correct ways, not alternatives :), to code my intention would be:
if (!a) a = expr;
or
a = a ? a : expr;
they should be optimized the same (I think) though personally I would prefer the first one (because it has one less a to type).
However, the second part of the question still remains. The arguments that Jens and Edmund about have given about the ambiguity in a ||= expr apply equally well to a = a || expr. the assignment case can simply be treated as the normal one:
convert a to boolean
if it is true, the value of the entire expression becomes equal to the boolean value of a
otherwise evaluate expr, convert result to boolean, assign to a, and return it
The steps above seem to be the same for both the assignment and normal case.
a ||= expr is problematic due to short circuit evaluation of its equivalent a = a || expr.
To have a ||= expr function like a = a || expr consider OP's assertion:
"In the statement a = a || expr ..., first both a and expr will be implicitly converted to "booleans","
This is not quite correct. expr will not be converted if a evaluates to true. This would make a difference should expr be something like scanf() or rand() or some function that affected the state of the program.
Code such as a ||= scanf("%d", &i) != 1; would only attempt to scan data with a false value in a. Although it would be possible to extend the language this way, additional short-circuit operators to the current set of || and && would likely cause more coding problems than clear simplifications.
On the other hand: A quick, if obfuscated, way to write code where functions return non-zero codes on error.
// Perform functions until an error occurs.
bool error = foo1();
error &&= foo2(); // Only valid if C was extended with &&=
error &&= foo3();
Because the return type of operators || and && is not the same as type of their left argument.
The return type of || and && is always int1, while the left argument may be any integral, floating point or pointer type. The operands also don't have to be of the same type. Therefore defining x ||= y as x = x || y and x &&= y as x = x && y as would be consistent with other augmented assignments would not be able to store the result in the argument for most types.
You could come up with other definitions, e.g. x ||= y as if(!x) x = y and x &&= y as if(!y) x = y, but that would not be exactly obvious and it is not that useful, so it was not included.
1In C++ it is bool.
I guess the simple answer is that || is a boolean operator: and in C, a "boolean" is 0 or 1. The operands are implicitly converted to booleans (I have not checked that that's what the spec actually says, but it's how C behaves), and the result is a boolean.
Altering the semantics to support this pattern may well be feasible -- until someone relies on || doing what it's always done.
I cannot find any particular reason, why the operators don't exist (in C99).
So the only reason I can find is, that there was no boolean type in C89, and those boolean operators were intended to be solely used in if's.
Example:
int i = 5;
/* This should not make any difference,
since or'ing with false, shouldn't change
the value... dib di dib diddy...*/
i ||= 0; /* Actually: i = i || 0, which gives 'true' */
i is now '1'', which for most people is pretty counter intuitive.
This operator obviously doesn't bring any clearence or coding improvement without the boolean type, that would make sence being or'd with another one.
In my opinion, the implementation of a ||= b; as if(!a) a = b; would be pretty straightforward and has aleardy been implemented by e.g. Lua.
So you're question seems to be a bit, why C has been designed the way it has been designed.
If this question was about C++, you could for example ask Bjarne Stroustrup and ask him, what had went into him. Since this is not the case, this seems to me to be kind of a dead end, because the standard has been written quite some time ago and you cannot really ask people anymore, why the h***.
On the other hand, this incomplete operator set should (in my opinion) aleardy have been made whole using a similar notation than yours, since in my opinion, there is no reason against it.
I hope I could help a little.
One simple explanation is this.
bool resultsComputeAll = false;
bool resultsUntilFirst = false;
for (int i = 0; i < 10; ++i) {
resultsComputeAll = compute(i) || resultsComputeAll;
resultsUntilFirst = resultsUntilFirst || compute(i);
}
Which one would be result ||= compute(i)? It's ambiguous so it's better to not define.
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.
I have been using ! (logical negation) in C and in other languages, I am curious does anyone know how to make your own ! function? or have a creative way of making one?
int my_negate(int x)
{
return x == 0 ? 1 : 0;
}
!e can be replaced by ((e)?0:1)
Remember the bang operator '!' or exclamation mark in english parlance, is built into the programming language as a means to negate.
Consider this ternary operator example:
(some condition) ? true : false;
Now, if that was negated, the ternary operator would be this
(some condition) ? false : true;
The common area where that can get some programmers in a bit of a fit is the strcmp function, which returns 0 for the strings being the same, and 1 for two strings not the same:
if (strcmp(foo, "foo")){
}
When really it should be:
if (!strcmp(foo, "foo")){
}
In general when you negate, it is the opposite as shown in the ternary operator example...
Hope this helps.
C considers all non-zero values "true" and zero "false". Logical negation is done by checking against zero. If the input is exactly zero, output a non-zero value; otherwise, output zero. In code, you can write this as (input == 0) ? 1 : 0 (or you can convert it into an if statement).
When you ask how to "make your own ! method", do you mean you want to write a function that negates a logic value or do you want to define what the exclamation-point operator does? If the former, then the statement I posted above should suffice. If the latter, then I'm afraid this is something that can't be done in C. C++ supports operator overloading, and if doing this is a strict necessity then I would suggest looking there.
If you want to overload an operator, the proper prototype is:
bool operator!();
I'm not a big fan of overloading operators, but some people like their syntactic sugar.
EDIT: This is C++ only! Put it in the definition of your class.