While relational (comparison) operators can be used to test whether a particular condition is true or false, they can only test one condition at a time. Often we need to know whether multiple conditions are true simultaneously. For example, to check whether we’ve won the lottery, we have to compare whether all of the multiple numbers we picked match the winning numbers. In a lottery with 6 numbers, this would involve 6 comparisons, *all* of which have to be true. In other cases, we need to know whether any one of multiple conditions is true. For example, we may decide to skip work today if we’re sick, or if we’re too tired, or if we won the lottery in our previous example. This would involve checking whether *any* of 3 comparisons is true.

Logical operators provide us with the capability to test multiple conditions.

C++ has 3 logical operators:

Operator | Symbol | Form | Operation |
---|---|---|---|

Logical NOT | ! | !x | true if x is false, or false if x is true |

Logical AND | && | x && y | true if both x and y are true, false otherwise |

Logical OR | || | x || y | true if either x or y are true, false otherwise |

**Logical NOT**

You have already run across the logical NOT unary operator in lesson 4.9 -- Boolean values. We can summarize the effects of logical NOT like so:

Logical NOT (operator !) | |
---|---|

Operand | Result |

true | false |

false | true |

If *logical NOT’s* operand evaluates to true, *logical NOT* evaluates to false. If *logical NOT’s* operand evaluates to false, *logical NOT* evaluates to true. In other words, *logical NOT* flips a Boolean value from true to false, and vice-versa.

Logical NOT is often used in conditionals:

1 2 3 4 5 |
bool tooLarge { x > 100 }; // tooLarge is true if x > 100 if (!tooLarge) // do something with x else // print an error |

One thing to be wary of is that *logical NOT* has a very high level of precedence. New programmers often make the following mistake:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> int main() { int x{ 5 }; int y{ 7 }; if (!x > y) std::cout << x << " is not greater than " << y << '\n'; else std::cout << x << " is greater than " << y << '\n'; return 0; } |

This program prints:

5 is greater than 7

But *x* is not greater than *y*, so how is this possible? The answer is that because the *logical NOT* operator has higher precedence than the greater than operator, the expression `! x > y`

actually evaluates as `(!x) > y`

. Since *x* is 5, !x evaluates to *0*, and `0 > y`

is false, so the *else* statement executes!

The correct way to write the above snippet is:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> int main() { int x{ 5 }; int y{ 7 }; if (!(x > y)) std::cout << x << " is not greater than " << y << '\n'; else std::cout << x << " is greater than " << y << '\n'; return 0; } |

This way, `x > y`

will be evaluated first, and then logical NOT will flip the Boolean result.

Best practice

If *logical NOT* is intended to operate on the result of other operators, the other operators and their operands need to be enclosed in parentheses.

Simple uses of *logical NOT*, such as `if (!value)`

do not need parentheses because precedence does not come into play.

Logical OR

The *logical OR* operator is used to test whether either of two conditions is true. If the left operand evaluates to true, or the right operand evaluates to true, or both are true, then the *logical OR* operator returns true. Otherwise it will return false.

Logical OR (operator ||) | ||
---|---|---|

Left operand | Right operand | Result |

false | false | false |

false | true | true |

true | false | true |

true | true | true |

For example, consider the following program:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> int main() { std::cout << "Enter a number: "; int value {}; std::cin >> value; if (value == 0 || value == 1) std::cout << "You picked 0 or 1\n"; else std::cout << "You did not pick 0 or 1\n"; return 0; } |

In this case, we use the logical OR operator to test whether either the left condition (value == 0) or the right condition (value == 1) is true. If either (or both) are true, the *logical OR* operator evaluates to true, which means the *if statement* executes. If neither are true, the *logical OR* operator evaluates to false, which means the *else statement* executes.

You can string together many *logical OR* statements:

1 2 |
if (value == 0 || value == 1 || value == 2 || value == 3) std::cout << "You picked 0, 1, 2, or 3\n"; |

New programmers sometimes confuse the *logical OR* operator (||) with the *bitwise OR* operator (|) (Covered later). Even though they both have *OR* in the name, they perform different functions. Mixing them up will probably lead to incorrect results.

Logical AND

The *logical AND* operator is used to test whether both operands are true. If both operands are true, *logical AND* returns true. Otherwise, it returns false.

Logical AND (operator &&) | ||
---|---|---|

Left operand | Right operand | Result |

false | false | false |

false | true | false |

true | false | false |

true | true | true |

For example, we might want to know if the value of variable *x* is between *10* and *20*. This is actually two conditions: we need to know if *x* is greater than *10*, and also whether *x* is less than *20*.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> int main() { std::cout << "Enter a number: "; int value {}; std::cin >> value; if (value > 10 && value < 20) std::cout << "Your value is between 10 and 20\n"; else std::cout << "Your value is not between 10 and 20\n"; return 0; } |

In this case, we use the *logical AND* operator to test whether the left condition (value > 10) AND the right condition (value < 20) are both true. If both are true, the *logical AND* operator evaluates to true, and the *if statement* executes. If neither are true, or only one is true, the *logical AND* operator evaluates to false, and the *else statement* executes.

As with *logical OR*, you can string together many *logical AND* statements:

1 2 3 4 |
if (value > 10 && value < 20 && value != 16) // do something else // do something else |

If all of these conditions are true, the *if statement* will execute. If any of these conditions are false, the *else statement* will execute.

Short circuit evaluation

In order for *logical AND* to return true, both operands must evaluate to true. If the first operand evaluates to false, *logical AND* knows it must return false regardless of whether the second operand evaluates to true or false. In this case, the *logical AND* operator will go ahead and return false immediately without even evaluating the second operand! This is known as short circuit evaluation, and it is done primarily for optimization purposes.

Similarly, if the first operand for *logical OR* is true, then the entire OR condition has to evaluate to true, and the second operand won’t be evaluated.

Short circuit evaluation presents another opportunity to show why operators that cause side effects should not be used in compound expressions. Consider the following snippet:

1 2 |
if (x == 1 && ++y == 2) // do something |

if *x* does not equal *1*, the whole condition must be false, so ++y never gets evaluated! Thus, *y* will only be incremented if *x* evaluates to 1, which is probably not what the programmer intended!

Warning

Short circuit evaluation may cause *Logical OR* and *Logical AND* to not evaluate one operand. Avoid using expressions with side effects in conjunction with these operators.

As with logical and bitwise OR, new programmers sometimes confuse the *logical AND* operator (&&) with the *bitwise AND* operator (&).

Mixing ANDs and ORs

Mixing *logical AND* and *logical OR* operators in the same expression often can not be avoided, but it is an area full of potential dangers.

Many programmers assume that *logical AND* and *logical OR* have the same precedence (or forget that they don’t), just like addition/subtraction and multiplication/division do. However, *logical AND* has higher precedence than *logical OR*, thus *logical AND* operators will be evaluated ahead of *logical OR* operators (unless they have been parenthesized).

New programmers will often write expressions such as `value1 || value2 && value3`

. Because *logical AND* has higher precedence, this evaluates as `value1 || (value2 && value3)`

, not `(value1 || value2) && value3`

. Hopefully that’s what the programmer wanted! If the programmer was assuming left to right evaluation (as happens with addition/subtraction, or multiplication/division), the programmer will get a result he or she was not expecting!

When mixing *logical AND* and *logical OR* in the same expression, it is a good idea to explicitly parenthesize each operator and its operands. This helps prevent precedence mistakes, makes your code easier to read, and clearly defines how you intended the expression to evaluate. For example, rather than writing `value1 && value2 || value3 && value4`

, it is better to write `(value1 && value2) || (value3 && value4)`

.

Best practice

When mixing *logical AND* and *logical OR* in a single expression, explicitly parenthesize each operation to ensure they evaluate how you intend.

De Morgan’s law

Many programmers also make the mistake of thinking that `!(x && y)`

is the same thing as `!x && !y`

. Unfortunately, you can not “distribute” the *logical NOT* in that manner.

De Morgan’s law tells us how the *logical NOT* should be distributed in these cases:

`!(x && y)`

is equivalent to `!x || !y`

`!(x || y)`

is equivalent to `!x && !y`

In other words, when you distribute the *logical NOT*, you also need to flip *logical AND* to *logical OR*, and vice-versa!

This can sometimes be useful when trying to make complex expressions easier to read.

Where’s the logical exclusive or (XOR) operator?

*Logical XOR* is a logical operator provided in some languages that is used to test whether an odd number of conditions is true.

Logical XOR | ||
---|---|---|

Left operand | Right operand | Result |

false | false | false |

false | true | true |

true | false | true |

true | true | false |

C++ doesn’t provide a *logical XOR* operator. Unlike *logical OR* or *logical AND*, *logical XOR* cannot be short circuit evaluated. Because of this, making a *logical XOR* operator out of *logical OR* and *logical AND* operators is challenging. However, you can easily mimic *logical XOR* using the *inequality* operator (!=):

1 |
if (a != b) ... // a XOR b, assuming a and b are Booleans |

This can be extended to multiple operands as follows:

1 |
if (a != b != c != d) ... // a XOR b XOR c XOR d, assuming a, b, c, and d are Booleans |

Note that the above XOR patterns only work if the operands are Booleans (not integers). If you need a form of *logical XOR* that works with non-Boolean operands, you can static_cast them to bool:

1 |
if (static_cast<bool>(a) != static_cast<bool>(b) != static_cast<bool>(c) != static_cast<bool>(d)) ... // a XOR b XOR c XOR d, for any type that can be converted to bool |

Quiz time

Question #1

Evaluate the following expressions.

Note: in the following answers, we “explain our work” by showing you the steps taken to get to the final answer. The steps are separated by a *=>* symbol. Expressions that were ignored due to the short circuit rules are placed in square brackets. For example

(1 < 2 || 3 != 3) =>

(true || [3 != 3]) =>

(true) =>

true

means we evaluated (1 < 2 || 3 != 3) to arrive at (true || [3 != 3]) and evaluated that to arrive at “true”. The 3 != 3 was never executed due to short circuiting.

a) (true && true) || false

b) (false && true) || true

c) (false && true) || false || true

d) (5 > 6 || 4 > 3) && (7 > 8)

e) !(7 > 6 || 3 > 4)

5.x -- Chapter 5 summary and quiz |

Index |

5.6 -- Relational operators and floating point comparisons |

When should the logical NOT be used versus the not equal to?

You should use != when you want to check if two things are not equal. You should use ! if you want to invert a result.

It's better to use != than ! (==) because it's both clearer what your intent is, and it's one operator instead of two.

Alex,

great work with these tutorials. I have learned so much in such a little time. Anyhow, I had this idea that it may be cool to combine all of your Rules onto one page (each rule is linked back to the section for context reference and such). anyhow... just thinking out loud here!

Yes, this is on my to-do list. :) Thanks for reminding me that I need to get around to actually doing it. :)

How to decide the operator precedence in a complex logical expression like this.

if(a > b && c != 0 || d <= a != 0)

We talk about precedence in lesson 3.1 -- Precedence and associativity.

Alex,

Is it true that the comparison operator == can be evaluated as bool true or false? The reason for asking this is does the comparison operator have an effect on the logical or operator. In the program above you wrote ( if ( value == 0 ll value == 1) ). If I'm not mistaken if a user enters a value of 1 or above the left side of the or is false and the right side is always true. So the if statement still evaluated as true. However if the user entered a 2, 3, or 4 . The wording in the cout statements would be wrong. A negative number would have the same effect. Wouldn't it?

Yes, operator== evaluates its operands and returns true if they are identical, and false otherwise. If the user entered a value of 2, the left hand side would evaluate to false, and the right hand side would evaluate to false, and false || false is false. The provided statement will only evaluate to true if value evaluates to 0 or 1.

Here is a simplified way to understanding how the logical NOT is distributed using De Morgan's law. This is under the assumption that the operators mentioned below are all boolean true.

In the following condition:

(x && y)

If one operand is true, and one false, then both are false. Both x and y have to be true.

If you don't want the overall condition to be true, i.e. !(x && y), you have to make sure that only one of the operands is false, i.e. make sure either x is false (!x), or y is false (!y).

This way the condition will always evaluate to false. Which would be written as: !x || !y

--------------------

In the following condition:

(x || y)

Only one operand has to be true.

If you don't want the overall condition to be true, i.e. !(x || y), you have to make sure that both operands are false, i.e. make sure x is false (!x) and y is false (!y).

This way the condition will always evaluate to false. Which would be written as !x && !y

--------------------

I hope this helps anybody trying to understand this!

Edit: This is under the assumption that the *operands mentioned below (i.e. x and y) are all boolean true.

Hello, can you tell me why this works as expected, i.e. a 0 return, assuming polje.at(x).at(y) is a ‘0’ or a ‘>’

but this does not (returns 1):

Is it because (‘0’ || ‘>’) evaulates to 1 and polje.at(x).at(y) is not a char code 1? Am I right?

Yes, you are correct.

Thank you for the quick answer.

<u>Typo</u>

Hey Alex,

Above, isn't the first 'Short circuit evaluation' in bold the sub-heading for the section that follows? Currently it is wrapped at the end of the paragraph before it. May seem silly, but it makes it trickier to read. Or is it a browser-specific issue? (I'm using Safari 8.0.3)

Thanks again for all these great stuff. :)

It was a formatting error. It's fixed now, thanks for pointing it out!

int x = 5;

int y = 7;

if (x == y)

cout << "x does not equal y";

else

cout << "x equals y";

Why do I get this: x equals y

Your logic is inverted. You check if x is equal to y, and if so, you print that they're not equal (and vice-versa).

In other words, your output statements need to be switched.

Hey Alex! (This does not concern this chapter)

Just want to know if I can skip a few chapters?

Like I I don't want to study the entire 4th section, can I skip that and move on to 5th? Or if I do this will section 5th be the most difficult for me to understand?

Depends on the lesson. Some lessons are super important, others are more situationally useful. Some are one-offs, others build on concepts over multiple lessons.

#include <iostream>

int main()

{

using namespace std ;

cout << "Enter a number: " ;

int value;

cin >> value ;

if ( value > 10 && value <

20)

cout << "Your value is

between 10 and 20" << endl;

else

cout << "You value is

not between 10 and 20" << endl;

return 0 ;

}

In this case, we use the logical AND operator to

test whether the left condition (nValue > 10) AND

the right condition (nValue < 20) are both true.

The variable closed in brackets is a variable that was never declared in the program. Variable declared in the program was named value (not nValue). I think you should update the paragraph (next to the program) in the logical AND operator section.

One typo:

Look at the example of logical AND. You left the character 'r' (r is missing from "Your") in your else statement. Sorry again for my bad english.

I fixed the typos. Thanks for pointing them out!

Typos.

"Logical not (NOT) is often used in conditionals"

"This is known as short circuit evaluation, and it is done primary (primarily) for optimization purposes." (User 'Cyrus' pointed this out)

"C++ doesn’t provide an (a) logical XOR operator."

In the following example (under 'Quiz answers'), shouldn't you use || instead of | for the OR operators?

"For example '(true | false) => true' means we evaluated '(true | false)' to arrive at the value 'true'."

In solutions 4 and 5, you mistakenly wrote '&' instead of '>':

"(5 & 6 || 4 & 3) && (7 & 8) =>"

"!(7 & 6 || 3 & 4) =>"

Alex, thanks for bearing so patiently with all my critiques! That takes some serious humility.

You are right on all counts. Good eye! Thanks.

Those who have checked out De Morgan's Law on Wikipedia, the colored region that's important in the Venn diagram is the light blue region.

For those who'd like to understand De Morgan's Law, I found that it doesn't work using AND and OR logic. It's only understandable if you use UNION(for AND) and INTERSECTION(for OR) logic.

If you'd like to understand the logic behind it, this is the best video I found explaining De Morgan's Law on YouTube:

De Morgan's Laws

Doesn't C++ provide the XOR operator through ^ ?

NVM that's Bitwise XOR, not Logical XOR!

You might want to update the link to De Morgan’s law:

http://en.wikipedia.org/wiki/De_Morgan%27s_laws

Thanks! Updated.

I came up with a pretty good analogy to help me understand the logical NOT's effect on the logical AND and OR:

Door = statement

Open Door = true statement

Closed Door = false statement

Logical AND:

1) You are walking through a long corridor. There are many doors in your path. In order to reach the other side (final statement=true),

allthe doors have to be open.Logical OR:

2) You are standing in a large room. There are many doors leading out of the room. In order to leave the room (final statement=true), at least one of these doors has to be open.

Now, when you add in the NOT:

1) If you didn't reach the other side, it means that at least one of the doors in your path was closed: The first one OR the second one OR the third one etc.

2) If you didn't leave the room, it means that

allthe doors were closed: the first one AND the second one AND the third one etc.You can clearly see how NOT turned the AND into OR and OR into AND.

I'm sorry, but your quiz section just looks like a gigantic headache to me.

I thought I knew what it was I had to figure out, but when I checked the answers it made me more confused.

I changed the == symbol to a => symbol to (hopefully) better indicate that the quiz answers are showing you a progression of steps to get to the final answer.

eg. (true | false) => true

means we evaluated "(true | false)" to arrive at the value "true".

Haha. pakyu all.

#include

int main()

{

using namespace std;

cout <> nValue;

if (nValue == 0 || nValue == 1)

cout << "You picked 0 or 1" << endl;

else

cout << "You did not pick 0 or 1" << endl;

return 0;

}

In your this program if I enter any letter , the output comes that I have picked 0 or 1.........

can anyone explain me this....

ulors. i dont understand your comment. ../..

please alex i don't understand about right and left shift please expan

I don't know if anyone will answer but i don't understand how Logical NOT works.

int x = 5;

int y = 7;

if (!(x == y))

cout << "x does not equal to y";

else

cout << "x equals to y";

wouldn't if (!(x == y)) translate to if (!(false))

and if the variable were equal wouldn't it translate to (!(true)) the conditions in the parentheses would be set either way, my question is how does else get called when it seems the conditions no matter what will always call the first cout. I could just be missing something but I am so confused.

Ok I think i get it. True executes the IF statements and False executes the Else statement. If its not that please do explain to me.

I have some issue with the logical NOT and || parameters.

My code is this:

...

int story(){

// kiválasztása a névnek és a nem-nek. A név nem befojásoló tényezõ viszont a nem igen

// mert másképp kell szólítani, hivatkozni rá!

cout << "Well then i think i can't do anything else. \n I tell one more good night story...\n\n";

cout << " But lets do it together litle pumkins. First what would be, he or she \? \n";

cout <> sex ;

// Fiú szála a történetnek

if (sex == "he")

{

// névadás a fiúnak

cout <> character_name; cout << "\n\n";

// a történet megkezdése

cout << " ___________________________________________________________________\n";

cout <<" It was a sunny day when our hero " << character_name << " went out with they wooden sword to play a litle outside.\n";

};

// lány szála a történetnek

if (sex =="she")

{

// névadás a lánynak

cout <> character_name; cout << "\n\n";

// a történet megkezdése

cout << " ___________________________________________________________________\n";

cout <<" It was a sunny day when our heroine " << character_name << " went out with they wooden sword to play a litle outside.\n\n\n";

};

if (sex != "he" || sex!="she") {

cout << "\t Your answer is invalid. Please be sure to tipe in he or she !\n\n\n";

return story();

};

return 0;

}

When you tipe in he or she it go and ask for the name as it needed but after giving the name the prograb drop up the error message that you dont tiped he or she. But it catch the problem too if someone dont tipe in he or she he dont let them furter and warn the user.

I dont know why it is drop out the error when the program once accepted it and let them go forward.

What i wanted to do is that if the user not give right ansver ( now its he or she ) then return to the beginning after the warning. But right now is either give he or she or give someting else its stuk in a loop. ( this is just a part of my code where are i think the problem should be)

Hi Alex and team,

Application of DeMorgan's Law is NOT explained in the answer of the last quiz question.

Shouldn't it be like this ?

!(7 > 6 || 3 > 4) == !(true || false)

== (!true && !false) == (false && true) == false

Correction: The application of De Morgan's law is NOT necessary in the answer of the last quiz question.

De Morgan's law is only necessary if you wish to remove the parentheses from the expression. Both your's and Alex's answers are correct.

Hi guys and Alex. First of all thanks a lot for this great tutorial. I understand all the information youv'e provided on logical operators or at least I think I do. However the quiz has totally threw me I don't understand it at all. If someone could break it down (the quiz) so it's easier to understand it would be much appreciated. Many thanks in advance.

^ this.

I don't understand the quiz at all. More explanation of the working there would be really helpful. I feel that I understood everything leading up to the quiz, but the format of the quiz was unexpected.

It confused me at first as well. The equality operator is stating that all the preceding (since the previous equality operator) is equivalent to the following. The first problem's answer could be read like this.

(true && true) || false

// (true && true): If one true is true, then both trues are true, so the above statement means the same as (or ==)

true || false

// Either true or false must be true, so the above statement evaluates as (or ==)

true

If it helps to clarify, ((true && true) || false) == (true || false) == (true). Basically, the goal is to simplify the expression as far as possible, noting the simplifications with ==. Hope that helps!

This also confused me. Even after I read what you wrote, Grimercy, it helped only a little bit. I still didn't understand the other questions. So while I drove to work I prayed to God. Then when I arrived home from work I understood everything.

First of all, in order to understand how to evaluate the questions we can refer to the tables Alex mentioned in this subchapter. I will rewrite them below.

Logical ORThe logical OR operator is used to test whether either of two conditions is true. If either the left operand evaluates to true, or the right operand evaluates to true, the logical OR operator returns true.

Logical OR (operator ||)

`false || false == false`

false || true == true

true || false == true

true || true == true

Logical ANDThe logical AND operator is used to test whether both conditions are true. If both conditions are true, logical AND returns true. Otherwise, it returns false.

Logical AND (operator &&)

`(false && false) == false`

(false && true) == false

(true && false) == false

(true && true) == true

After reiterating the information in the tables from logical OR, and logical AND, we can now answer the questions.

1) (true && true) || false

== true || false

== true

2) (false && true) || true

== false || true

== true

3) (false && true) || false || true

== false || false || true

== false || true

== true

`4) (5 > 6 || 4 > 3) && (7 > 8)`

== (false || true) && false

== true && false

== false

Question 5 can be evaluated as is:

5) !(7 > 6 || 3 > 4)

== !(true || false)

== !(true)

== false

Or it can be evaluated by removing the parentheses and using De Morgan's law:

5) !(7 > 6 || 3 > 4)

== !(true || false)

== !true && !false

== false && true

== false

As you can see, the result is exactly the same.

Heyyy, look at me! I have a nice, polished, streak-free new account! Check out the shine on this baby. :)

About the quiz questions for this section of the chapter, I know they are meant to test my knowledge of the level of precedence logical AND and logical OR operators have when used in the same expression, but I can't figure out how to "answer" them after Quiz Question #3.

I got the first two fine, but I get a little lost when the third one goes into "|| true == false". I thought it would be "|| false == false" or "|| false == true", not the other way around?

I know it seems like a trivial question, but I need to understand this.

This is known as short circuit evaluation, and it is done

for optimization purposes.

Should be PRIMARILY :]

so how do you get these symbols in Code::Blocks

...you type them, just like anywhere else. they're on your keyboard

Can you use the logical operators in do...while loops? I try to check an user-entered integer if it's between 1 and 10. I use the && operator, but I can't get it to work properly.

Here's the code:

Whatever value I enter, the program always goes to the next part. If I check either

or

it works properly, but I can't check both at the same time...

Never mind... I see my mistake; I should've used the || operator.

Thanks for a great tutorial, Alex!

Kaonashi

"int nInvoer=0;

do

{

cout <> nInvoer;

}

while (nInvoer = 10 );

// Do here if entered value is between 1 and 10.

Your problem is actually that you have your comparison operators reversed. You want to evaluate between 1 and "&&" 10. As you have it written it will always come up false. This is because you are asking for less than "=", both can never be true of the same variable, thus it will always be false. If you change your and "&&" to or "||" you will instead be checking if the number entered is not between 1 and 10.

the correction for this is:

while (nInvoer >= 1 && nInvoer <= 10 );

This will check for any number including and between 1 and 10.

Hey Ronnie,

I just thought about your XOR question and came to this solution (since their is no XOR to use directly in c++)

(!america && russia) || (america && !russia)

lets just take a logic look behind this:

So basically with only 2 conditions it is easy to handle. How did you manage to pick that example?! :)

wish you all a nice weekend

Florian

Hi Alex. Love the tutorials, especially how you try to relate things back to machine code and whatnot. Truly deepens my understanding. Quick question: is there not an exclusive OR? i.e. if either x OR y are true, but NOT if both are? i.e.

America has nukes / Russia has nukes / World gets destroyed

false / false / false

true / false / true

false / true / true

true / true / false [MAD theory ;)]

Or is there a combination of ANDs and ORs and NOTs to achieve this?

C++ doesn't provide an exclusive or operator. I've added an example of how to mimic XOR behavior using operator!= into the lesson.

Thank you for providing such an excellent example for mimicing logical XOR behavior using the != operator.

Hello Alex,

Your workaround for the missing xor can only deal with booleans. To fix this use:

The ! operator will make sure the operands are bool before the != gets evaluated. This way it will work on anything that can be cast to bool. Note that xor has the same result when all operands are inverted.

That's kind of neat. While not likely to be used very often, neither is XOR in general. I've added it to the lesson.

This only works if there is an equal number of operands.

If you have an equal number of operands and an odd number of them are true, there also must be an odd number of false operands. On the other hand, if you have an odd number of operands and an equal number of them are true, there must be an odd number of false operands.

Double negation (i.e. (!!a != !!b != !!c)) or static casts work for both odd and equal number of operands.

It appears you are correct. I've updated the lesson to use static_cast instead, since doing a double-negation likely has more performance impact.

Since you updated the lesson to use static_cast, you should get rid of the sentence "In this form, the logical NOT operator is used to convert the operand to an inverse boolean value. However, XOR evaluates the same way when all operands have been inverted, so this does not impact the result".

Thanks -- sentence removed!

I'm probably splitting hairs with this comment, but in the

Logical ORsection you say the following:However, if the left operand is true, a "short circuit" occurs. In other words, if the left operand is true, the right operand is not even evaluated because the entire statement is already true (so technically, it's not possible for both operands to evaluate to true in a logical OR). Consider the following code snippet. In this case, "True" will always be printed (the right operand is never evaluated because of the short circuit, even though dividing by zero is illegal):

I redid the wording to disambiguate, and added a note about short circuit evaluation of logical OR. Thanks!

Just wondering, if this "short circuit" is something which is compiler dependent. There could be many architectures (esp DSP processors) where multiple instructions can be issued on multiple ALUs (VLIW architectures). For e.g. in (x == 1 && y++ == 2), compiler might generate a code for (x==1) and y++ to go in the same cycle. Do you think it is mandatory that compilers have to implement "short circuit".

Short circuit evaluation is guaranteed in C++ with the fundamental data types. However, it's worth noting that if you override the || or && operator for your own classes, short circuit evaluation is not performed when used in those cases. For that reason, operators || and && normally aren't overridden.