Reputation: 4470
I ran into an interesting line of code today. I did not know it was legal to use the word "or". I thought there was only ||. What is this called and where can I read more about it? Thanks
if (V_discount == "y" or "Y" or "Yes" or "yes")
{
cout << "Your discount is: ";
}
edit: It turns out the if statement doesn't do much. I put a cout<<"hi"; in the brackets, and it executes regardless of what V_discount has in it.
I thought it was called something because netbeans is highlighting "or" in blue.
2nd edit:
v == "y" || "Y"
is not the same as
v == "y" || v == "Y"
Only the latter functions "as intended". "As intended" being checking whether v is the string "y" or v is the string "Y".
Upvotes: 2
Views: 279
Reputation: 263457
It's called an "alternative token", documented in section 2.6 [lex.digraph] of the current ISO C++ standard, and in section 2.5 of the 1998 ISO C++ standard. (This is the same section that defines "digraphs", such as <%
for {
and %:
for #
.)
But the code you've shown uses it incorrectly.
First, if x
were an int
, then you'd probably want this:
if (x == 10 or x == 20 or x == 30)
rather than this:
if (x == 10 or 20 or 30)
The latter is actually legal, but it means something quite different.
And comparing strings for equality is not straightforward. If V_discount
is a char*
or char[]
, then comparing V_discount == "yes"
compares pointer values, not the contents of the strings, and they'll certainly compare unequal. If V_discount
is a std::string
, then I think it will work -- but you still have to compare it to each of the literals individually. Otherwise, as Tony Delroy's answer says, it compiles but does something entirely unexpected involving implicit conversions to bool
.
Upvotes: 7
Reputation: 106196
I ran into an interesting line of code today. I did not know it was legal to use the word "or". I thought there was only ||. What is this called and where can I read more about it? Thanks
It's legal. Sadly, the Microsoft Visual C++ compiler doesn't support it (at least by default - maybe there's an obscure command line switch or something). Because of the lack of portability, even people who know about them (or
, and
, xor
) and prefer them stylistically may decide not to use them.
if (V_discount == "y" or "Y" or "Yes" or "yes") { cout << "Your discount is: "; }
"y" "Y" "Yes" and "yes" are all string literals - basically compiler-generated character arrays of the quoted text and a NUL terminator suffix (i.e. the "C" string representation, for ASCII text the ASCIIZ name is often used - Z referencing the zero/NUL value of the final byte). When these values are combined in an logical or
expression, they first decay to pointers to the first character, then the pointers are quietly converted to bool
values that can be ORed together. The pointers will all be non-0 values addressing the respective character buffers, and when promoting integral values to bool
C++ considers any non-0 value to be true
(and 0 false
). So, the entire expression is equivalent to (V_discount == "y") or true or true or true
. Anything or true
is true
, so the if
statement always executes the following statement block, as you found...
edit: It turns out the if statement doesn't do much. I put a cout<<"hi"; in the brackets, and it executes regardless of what V_discount has in it.
I thought it was called something because netbeans is highlighting "or" in blue.
Editors often have a list of "keywords" significant in the languages they support, typically with various sub-categories corresponding to on-screen (or -printer) style, but that doesn't necessarily correspond to the language Standard's classifications. In C++, or
is just a functionally-identifical alternative to ||
, and both are called "or" or - more precisely and to differentiate them from the bitwise version - "logical or".
2nd edit:
v == "y" || "Y" is not the same as
v == "y" || v == "Y"
Only the latter functions "as intended". "As intended" being checking whether v is the string "y" or v is the string "Y".
Generally true. If v
is a user-defined type and the ||
operator is overloaded (replaced) by the programmer, it can actually operate "as intended", but we C++ programmers are so used to typing the second form (which works for inbuilt and Standard library value-semantic types like int and std::string
) that we find having the v == "y" || "Y"
"work" as per v == "y" || v == "Y"
incredibly confusing, and invariable the C++ literature recommends against changing the weird but developer-familiar way of interpreting the former statement.
Note that given char v[some-number];
and candidate text in v
, the above comparison would need to do the written strcmp(v, "y") or strcmp(v == "Y")
.
Upvotes: 2
Reputation: 183446
The C++ Programming Language (page 829) just refers to them as "keywords", not giving them any special name. The C++11 standard (section 2.6) calls them "alternative token representations", but also includes e.g. <%
(for {
) under that name (which, I suppose, explains why it can't just call them "keywords"); I don't know if earlier standards used the same terminology.
Wikipedia calls them "operator synonyms", but that name doesn't seem to be in currency elsewhere.
Upvotes: 2