112

This is the only place I've ever seen and, or and not listed as actual operators in C++. When I wrote up a test program in NetBeans, I got the red underlining as if there was a syntax error and figured the website was wrong, but it is NetBeans which is wrong because it compiled and ran as expected.

I can see ! being favored over not but the readability of and && or seems greater than their grammatical brothers. Why do these versions of the logical operators exist and why does seemingly no one use it? Is this truly valid C++ or some sort of compatibility with C that was included with the language?

Wolf
  • 9,679
  • 7
  • 62
  • 108
defectivehalt
  • 2,462
  • 3
  • 21
  • 22
  • 5
    \me Rewrites all his code – lmat - Reinstate Monica Mar 10 '16 at 15:42
  • 2
    in the spirit of "clean code" I'd personally recommend to do away with the habit of writing `||` and `&&`, maybe even `!` at times. Words are always better then "line noise", not to mention the possible confusion with the bit manipulation operators. – Ichthyo May 24 '16 at 20:53
  • 4
    @Ichthyo That isn't always correct. It's way faster to read a lot of symbols and know the meaning of them, than reading a lot of words. – vallentin Aug 29 '16 at 19:04
  • what is clearer for a human reader depends on the "Gestalt". Sometimes a symbol can be clearer than some muddled term, but in this case it isn't. And, simple words of the English language are way more universal than some weird special symbols of a somewhat strange programming language... – Ichthyo Oct 03 '16 at 15:50
  • 10
    The irony of saying that `and` is more readable and then writing "`and` && `or`" though :) – Ivan Vergiliev Aug 08 '17 at 11:57
  • 1
    @Ichthyo Have you ever programmed Fortran? In Fortran you'd get your heart's desire: Virtually everything that's a symbol in C/C++/Java is a keyword in Fortran. You get `begin`, `end`, `contains`, `pointer`, `allocatable`, `extends`, etc. I'd run fast in the opposite direction if someone offered me to work with Fortran again, but, hey, maybe that's a task for you? ;-) Honestly, the use of symbols for vital stuff in C/C++/Java is a feature, not a bug. It allows your eyes to *quickly recognize a single symbol* instead of parsing and interpreting a word instead. – cmaster - reinstate monica Jan 14 '19 at 19:07
  • 1
    @cmaster please stop twisting the facts. A word like "and" can be grasped visually, without the need to parse letters and decipher it. That is the whole point of learning to read. And the whole point of being a true nerd is to find line noise literally self explanatory. – Ichthyo Jan 16 '19 at 00:35
  • 1
    @Ichthyo Don't you find the expression "twisting facts" a little stark when all I did was to tell you about my *experience*? The beauty of the `||` operator is, that it stands out *visually*. The beauty of the `{}` block delimiters is, that they stand out *visually*. In C/C++/Java I can grasp the overall structure of an expression without actually reading anything. `r > 0 && x*x + y*y > r*r` is clear and concise, `r is greater than 0 and x times x plus y times y is greater than r times r` is not. Really, do some Fortran programming before you tell me my experience is wrong! – cmaster - reinstate monica Jan 16 '19 at 09:14
  • The readability of the `and` and `&&` is also influenced by the editor. My editor boldfaces these word tokens. The visual support makes a difference. – shuhalo Jul 29 '20 at 23:10

5 Answers5

132

They originated in C in the header <iso646.h>. At the time there were keyboards that couldn't type the required symbols for && (for example), so the header contained #define's that would assist them in doing so, by (in our example) defining and to be &&. Of course, as time went by this became less used.

In C++, they became what are known as alternate tokens. You do not need to include anything to use these tokens in a compliant compiler (as such, the C++-ified version of the C header, <ciso646>, is blank). Alternate tokens are just like regular tokens, except for spelling. So during parsing and is exactly the same as &&, it's just a different way of spelling the same thing.

As for their use: because they are rarely used, using them is often more surprising and confusing than it is helpful. I'm sure if it were normal, they would be much easier to read, but people are so used to && and || anything else just gets distracting.

EDIT: I have seen a very slight increase in their usage since I posted this, however. I still avoid them.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • So is the interpretation of these alternate tokens just a compiler feature or is it in the C++ specification? – defectivehalt Mar 04 '10 at 02:44
  • 3
    @Kavon: It's specified in section 2.5 of the standard; it's a language feature. – GManNickG Mar 04 '10 at 02:53
  • 22
    I personally think they are much better... but then I am Python biased. I don't know why some people thing that if it's not garbled it's not code... – Matthieu M. Mar 04 '10 at 08:28
  • So these are not valid in C without including that header file? I am surprised that these are not used by everyone; they make Python so much more readable. – endolith Mar 05 '13 at 15:48
  • 1
    At least Visual Studio 2015 CTP 6 did not like my `or` or `not` without including the header. – usr1234567 Mar 15 '15 at 22:25
  • Could you add which version of the C++ standard introduced these? – Mark Ransom Jun 06 '17 at 04:47
  • @usr1234567 Microsoft disables alternative tokens thus violating [lex.digraph] when "Language Extensions" are enabled (and they are by default). When extensions are disabled, they do work. – Sergey.quixoticaxis.Ivanov Jul 18 '17 at 11:51
  • @MarkRansom: All versions of the C++ standard have them. – Nicol Bolas Jan 14 '19 at 18:48
  • Just gonna throw this out there... But any programmer who is suprised/confused to the point that they have difficulty reading code that uses `and` instead of `&&` should probably not be a programmer. po-tay-to po-tah-to. – tjwrona1992 Mar 11 '19 at 15:06
  • 1
    Not *exactly*. `#define STR(x) #x` and then `STR(and)` != `STR(&&)`. – L. F. Jul 15 '19 at 07:49
  • Talking about these alternative tokens in ``, while `not_eq` is defined for `!=`, there is nothing defined for `==` :D – aafulei Dec 10 '22 at 04:45
  • 1
    @usr1234567 • Visual Studio needs `/permissive-` compiler flag to enable these standard C++ keywords, otherwise `#include ` will opt-in allow them. For backwards compatibility, Visual Studio has language extensions enabled, which also disable some standard language features. – Eljay Jun 01 '23 at 16:02
24

They do exist for usability (character support in keyboard/display flavors) and general readability, but there's another reason that's nowadays more pronounced. Almost none of the answers here, here, or even the main answer here spell out the core reason many of us prefer the word versions over the symbol versions (and a main reason other languages use them): bugs. The differences between the word versions are very visible. The differences between the symbol versions are markedly less so, to the point of tempting bugs to a comparatively much greater extent: "x|y" is very much not "x||y", yet when embedded in a larger expression many of us miss the difference. It's similar to the common accidental mixing of the assignment vs equality operator. For this reason I've weaned myself off of the symbol versions (it wasn't easy) in favor of the word versions. I'd rather have someone do a double-take on them due to our love of old things than tempt bugs.

Community
  • 1
  • 1
mr3
  • 369
  • 2
  • 6
  • 4
    Unfortunately, in Visual Studio (as of VS2013), you must set a specific compiler option (`/Za`) in order to support the alternative keywords (see http://stackoverflow.com/a/555524/368896). That presumably also has other impacts. So, in Visual Studio, it's not necessarily safe to take this advice. – Dan Nissenbaum Jun 11 '14 at 19:10
  • FWIW /- as I put spaces around operators, `x | y` is sufficiently visually distinct (in monospaced fonts) from `x || y`, but I do find the `!` in e.g. `if (!f(xyz) && ...` easier to miss than `if (not f(xyz) && ...`. – Tony Delroy Aug 20 '15 at 06:00
  • @Tony D when you put spaces around operators, that is your private convention and not obvious to the reader. But using natural language words like `and`, `or` and `not` in a boolean expression, actually improves readability plus it highlights the distinction to bit manipulations. Thus IMHO we should consider to change our beloved old habits to the better... – Ichthyo May 24 '16 at 21:03
  • @DanNissenbaum I found this option under the name *C/C++ > Language > Disable Language Extensions*, so it's relatively safe to expect side effects ;) – Wolf Jan 10 '17 at 12:20
  • 6
    Do you know how many Python bugs have been introduced because the words `and` and `or` bias people's thinking of how they should work? E.g. `if (a == b or c)` instead of `if (a == b || a == c)` - something like this pops up almost every day here at StackOverflow. Abstract symbols that are disconnected from the English language reduce these errors. – Mark Ransom Jun 06 '17 at 04:53
  • 1
    Do you think people would be less likely to misuse operator precedence if logicals were symbol-based? I see that as a separate issue unaffected by how logicals are represented...so much so that my advice to green Python users (especially w/Python being the 1st language for so many) would be to just use parentheses until they learn. That's just me though. Ironically, w/the current group I'm in using symbols exclusively, I use them now too. I just have to be more careful, which is an approach that helps w/precedence too. – mr3 Jun 08 '17 at 15:16
11

In C++, they are real keywords. In C, they're macros defined in <iso646.h>. See http://web.archive.org/web/20120123073126/http://www.dinkumware.com/manuals/?manual=compleat&page=iso646.html.

endolith
  • 25,479
  • 34
  • 128
  • 192
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • 6
    Technically they are alternate tokens, not keywords. :) – GManNickG Mar 04 '10 at 02:15
  • 2
    @GMan: +1 Nice call, though, the Dinkumware page calls them keywords, so, I suppose they didn't care too much about the distinction. – C. K. Young Mar 04 '10 at 03:31
  • Updated link: http://f3.tiera.ru/1/addesio/computer-science/C&C++/%E7%AC%AC%E4%B8%89%E6%96%B9%E7%9A%84C%E5%92%8CC++%E5%BA%93/Dinkumware%20Library/dinkumware/htm_cl/iso646.html – kevinarpe Jul 18 '14 at 05:25
  • So, does MSVC support them out of the box in C++ but not in C? – rwst Oct 29 '15 at 07:11
  • 1
    @rwst I can't comment on MSVC specifically, but if it implements the C++ and C standards faithfully, then that will indeed be the case. See also: http://stackoverflow.com/questions/2376448/the-written-versions-of-the-logical-operators#comment37306872_20642363 – C. K. Young Oct 29 '15 at 07:19
  • @rwst in VS2015 you still need `#include ` and most (if not all) IDEs don't show them as keywords. – Wolf Jan 10 '17 at 10:52
  • see also [the `/Za` option in VS2013+](https://stackoverflow.com/questions/2376448/the-written-versions-of-the-logical-operators#comment37306872_20642363) – Wolf Jan 10 '17 at 12:12
  • @ChrisJester-Young only now I see what you mean by "See also: " ;) BTW: is there an IDE-integrated config option for it in VS2015, rather than via *C/C++ > All Options > Additional Options* ? – Wolf Jan 10 '17 at 12:14
  • 1
    for the C header see also http://en.cppreference.com/w/c/language/operator_alternative – Wolf Jan 10 '17 at 12:24
6

and and && are functionally the same in C++. The and and or operators are truly valid C++ and part of the language standard.

To elaborate on other answers with a concrete example, there is another reason besides just "readability" to prefer and over &&. Spelling out "and" explicitly when a logical AND is what you mean eliminates the possibility of subtle bugs.

Consider this:

int x = 3;
int y = 4;

// Explicitly use "and"
if (x and y) {
    cout << "and: x and y are both non-zero values" << endl;
}

// Using "&&"
if (x && y) {
    cout << "&&: x and y are both non-zero values" << endl;
}

// Oops! I meant to type "&&"!
if (x & y) {
    cout << "&: x and y are both non-zero values" << endl;
}
else {
    cout << "How did I get here?" << endl;
}

All three if-statements will compile, but the last one means something entirely different and unintended!

If you always use and when you mean logical AND, you can never accidentally type a single "&" and have your code compile successfully and run with mysterious results.

Another good exercise: Try leaving off a character of "and" by accident and see what happens. ;)

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • 2
    This is not really an answer to the question. It's just you stating what you feel is more legible. The OP asked about how the written versions work, not which are better. And [someone else](https://stackoverflow.com/a/20642363/734069) already made the same point you're trying to make. – Nicol Bolas Jan 14 '19 at 18:50
  • 1
    Not that it really provides any more useful information but I'll add "`and` and `&&` are functionally identical" to the answer... And if you read my answer you'd see that I'm saying its NOT about legibility ;) – tjwrona1992 Jan 14 '19 at 19:01
2

Try searching this page for usage of the logical operators. && or || is very easy to find. On the other hand, searching for and or or will give a lot of false positives.

The symbol versions also play more nicely with plain text files. If && appears in a comment or documentation, I immediately grok that the author meant the logical operator. If an and appears in documentation, the text styling probably tells me which is meant. If an and appears in a comment... sorry but word recognition doesn't tell me its function in the comment.

Did you even see that last use of and, without the text styling to help?

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720