• FEATURED
• FEATURED
• FEATURED
• FEATURED
• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Logical OR operator

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

20 replies to this topic

### #1Boooke  Members

Posted 21 February 2012 - 03:10 PM

Hello. I'm currently reading the Primer Plus 5th Edition. I'm currently stuck at the listing 6.4. It goes something like this,

#include <iostream>
int main()
{
using namespace std;
cout << "This program may reformat your hard disk\n"
"Do you wish to continue? <y/n> ";
char ch;
cin >> ch;
if (ch == 'y' || 'Y')
cout << "You were warned!\a\a\n";
else if (ch == 'n' || 'N')
cout << "A wise choice ... bye\n";
else
cout << "That wasn't a y or n, so I guess I'll "
return 0;
}


The problem is, no matter what the input will be, the program will always execute the first if-loop. So an input of 'n' or 'a' will result in the output "You were warned!". I have encountered this problem with the or operator in my own programs (On two different computers actually), and often thought I was just misusing it, but somehow I wonder if it's not me, and maybe some kind of bug? I suspect the OR operator since, if I remove it in all of the loops and leave only one char for each loop ('y' and 'N' for instance), the problem will disappear.

I am using Code::Blocks 10.05 (rev 6283) with the GNU GCC version 0.99 compiler (Which came with the Code::Blocks bundle). Hope someone can explain what is happening here.

Best regards,
Boooke

### #2BSt  Members

Posted 21 February 2012 - 03:22 PM

It should be:
(ch == 'y' || ch == 'Y')

@Down: a few secs.
(( I am learning English. ))

### #3Serapth  Members

Posted 21 February 2012 - 03:23 PM

Change it to:

if (ch == 'y' || ch == 'Y')

/EDIT: Too slow, too slow.

### #4Telastyn  Members

Posted 21 February 2012 - 03:26 PM

C++ sucks.

'Y' is a simple ascii character, value of 89. Since that's not zero, C++ allows implicit conversion of 89 into 'true'. So no matter what ch == 'y' is, the other side of the operator is true, thus the conditional is always true.

### #5WavyVirus  Members

Posted 21 February 2012 - 03:44 PM

ch == 'y'

In C++, this is an example of an "expression". This one evaluates to TRUE.

'Y'

Even a literal value can be considered an expression. This one evaluates to the character 'Y', which has the value TRUE if converted to a boolean (which is the case for anything non-zero converted to a boolean).

The || operator expects an expression on either side: a || b , where a and b are both expressions which are to be evaluated. The values of a and b are considered as booleans. If either are TRUE then the value of a || b is also TRUE. C++ will check a first and not actually go to the trouble of working out the value of b if a is TRUE.

a || b is also an expression - they are like Russian dolls stacked inside each other.

ch == 'y' || 'Y'

This expression from inside your 'if' is therefore equivalent to (ch == 'y') || ('Y'), or (expression which may be TRUE) || (TRUE).

### #6Boooke  Members

Posted 21 February 2012 - 04:16 PM

Ah, I understand now. Seems logical enough, though. Thank you for all the replies. It really helped clear a lot of trouble :-) Could you say something like ch == ('y' || 'Y') in such a loop? Gonna try it out when I get near an IDE.

Edit: Nope you can not :-(

### #7WavyVirus  Members

Posted 21 February 2012 - 05:54 PM

Like ||, the == operator expects an expression on either side. a == b evaluates both expressions first, compares the values and returns TRUE if they are equal.

You cannot use || to chain together values into a list of possible options like this. (a || b) does not mean of "a value which is either a or b", instead think of (a || b) as a true/false question which has to be answered before moving on: if (a is equal to TRUE) or (b is equal to TRUE) then the answer is TRUE else it's FALSE.

Generally the computer has to work out the values of things one by one - the various sub-expressions which make up a larger expression have to be evaluated (literally given a value and stored somewhere) in a particular order, just like a person would when working through a maths problem with lots of brackets etc.

### #8RulerOfNothing  Members

Posted 21 February 2012 - 08:55 PM

While what has been said above is true and useful, if you want to have an option be activated by both lowercase and uppercase letters, you can use the toupper function to avoid having to compare against both lowercase and uppercase letters. This is useful if you have a lot of options, as it eliminates the possibility of you (or someone else working on a program you wrote) forgetting to put in a test for either the lowercase or uppercase.

### #9LorenzoGatti  Members

Posted 22 February 2012 - 03:32 AM

An interesting newbie-friendly heuristic could be applied: there is no way to add parentheses in a way that makes any sense, so the expression must also be wrong without them.
ch == 'y' || 'Y'
Deceptively symmetrical.
ch == ('y' || 'Y')
Logical OR of two char constants? Whatever it does, it's not something I want to compare ch with; "at best" it is 'y' or 'Y', and I'm making only one of the two comparisons.
(ch == 'y' )|| 'Y'
Logical OR of operator == and a char constant? No, I want operator == on both sides.

Omae Wa Mou Shindeiru

### #10haegarr  Members

Posted 22 February 2012 - 04:14 AM

Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79hex
'Y' in ASCII / UTF-8 is 59hex
the difference is just 20hex, what is typical for all latin letters. Hence
( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.

EDIT: Well, I'm aware of the above being not a direct answer to the OP, also IMHO previous posts have given ample answers already. The above stuff came to my mind during reading RulerOfNothing's post about using toupper, because the above code is a kind of tolower-operator (although working for latin letters in said encodings only). So feel free to ignore it.

Edited by haegarr, 22 February 2012 - 07:20 AM.

### #11Boooke  Members

Posted 22 February 2012 - 04:21 AM

Hey again. I understand then. I really liked the idea of the toupper (and similar) function. I have used similar in before, but not in C++. It has quite some uses. Could help eliminate lines of code.

Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79hex
'Y' in ASCII / UTF-8 is 59hex
the difference is just 20hex, what is typical for all latin letters. Hence
( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.

I haven't worked with the bit-wise operators before, so I wouldn't know why it would work, and how it compares, though.

### #12rip-off  Moderators

Posted 22 February 2012 - 04:34 AM

( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.

This is "for beginners". And even if it were not - if I saw code like that, I wouldn't have a clue what it was trying to do at first glance.

### #13BSt  Members

Posted 22 February 2012 - 10:10 AM

@Edited: I got wrong.
(( I am learning English. ))

### #14rip-off  Moderators

Posted 22 February 2012 - 10:35 AM

That does not work. It is interpreted as the expression 'y' or ('Y' == ch), which is always true.

### #15Cornstalks  Members

Posted 22 February 2012 - 10:59 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

Ignore this. I'd delete it but then SiCrane's post wouldn't make sense. Learn something new every day.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #16SiCrane  Moderators

Posted 22 February 2012 - 11:01 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

### #17Cornstalks  Members

Posted 22 February 2012 - 11:45 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

I, good sir, am a moron. Thanks for the correction. I get so used to using the symbols that I forget that keywords like and, or, xor, etc. even exist.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #18Serapth  Members

Posted 22 February 2012 - 11:54 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

... learned something new.

Oddly enough, I don't think I have ever encountered it in use.

### #19SiCrane  Moderators

Posted 22 February 2012 - 01:04 PM

It's only really used by people who's keyboards don't have a convenient key for |. So like code written by Danish people ten or more years ago.

### #20Cornstalks  Members

Posted 22 February 2012 - 01:08 PM

It's only really used by people who's keyboards don't have a convenient key for |. So like code written by Danish people ten or more years ago.

So that's why Bjarne Stroustrup included them...
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.