36

I have some code that looks like:

static const std::string and(" AND ");

This causes an error in g++ like so:

Row.cpp:140: error: expected unqualified-id before '&&' token

so after cursing the fool that defined "and" as &&, I added

#ifdef and
#undef and
#endif

and now I get

Row.cpp:9:8: error: "and" cannot be used as a macro name as it is an operator in C++

Which leads to my question of WHEN did "and" become an operator in C++? I can't find anything that indicates it is, except of course this message from g++

Bill
  • 14,257
  • 4
  • 43
  • 55
boatcoder
  • 17,525
  • 18
  • 114
  • 178
  • 7
    It was first introduced into C94, i think. See http://www.lysator.liu.se/c/na1.html . While being macros in C, they are preprocessor operators in C++ so you can not `#define` them. (They are not keywords, technically. But also not all keywords are reserved in such a way. One which is, is `new`. One which is not, for example, is `sizeof`. So you may `#define sizeof`). – Johannes Schaub - litb Mar 10 '10 at 19:21
  • For that, notice this issue report: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#369 . Currently a `#define` of `delete` or `new` is not allowed. – Johannes Schaub - litb Mar 10 '10 at 19:31
  • 2
    Just as an FYI for MSVC users, if you want them to work in MSVC you need to enable the `/Za` option to put the compiler in strict ANSI mode or you need to include `iso646.h` (or `ciso646`). – Michael Burr Mar 10 '10 at 20:11
  • 2
    Of course, why you're creating a `std::string` where a `const char*` would work just fine and optimize better is another question... as is why you would want to define an alias for `" AND "`... It's not like the next version of SQL is threatening to change it to `" AHND "` and break things... – Mike DeSimone Mar 10 '10 at 20:11
  • 1
    Turns out that in C, these are only keywords if you include iso646 but in C++ they are always keywords. g++ just happens to be a little more up to date in regards to the spec. – boatcoder Mar 13 '10 at 17:09

7 Answers7

32

From the C++03 standard, section 2.5:

2.5 Alternative tokens

Alternative token representations are provided for some operators and punctuators. In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling. The set of alternative tokens is defined in Table 2.

Table 2—alternative tokens

alternative primary 
  <%         { 
  %>         } 
  <:         [ 
  :>         ] 
  %:         # 
  %:%:       ## 
  and        && 
  bitor      | 
  or         || 
  xor        ˆ 
  compl      ˜ 
  bitand     & 
  and_eq     &= 
  or_eq      |= 
  xor_eq     ˆ= 
  not        ! 
  not_eq     != 
interjay
  • 107,303
  • 21
  • 270
  • 254
15

They've been there since C++ 98. They're listed in the §2.5/2 of the standard (either the 1998 or the 2003 edition). The alternate tokens include: and, or, xor, not, bitand, bitor, compl, and_eq, or_eq, xor_eq, not, not_eq.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
12

You can use -fno-operator-names to disable this. Alternatively, you can name your std::string object something else!

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
DSB
  • 417
  • 1
  • 4
  • 8
11

There are several such alternatives defined in C++. You can probably use switches to turn these on/off.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
6

According to C++ Standard 2.12 there are predefined preprocessor tokens "which are used in the syntax of the preprocessor or are converted into tokens for operators and punctuators." and is one of them. In new C++ Standard there is new 2.12/2:

Furthermore, the alternative representations shown in Table 4 for certain operators and punctuators (2.6) are reserved and shall not be used otherwise:

and and_eq bitand bitor compl not
not_eq or or_eq xor xor_eq
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
4

They were added because some of those characters are difficult to type on some keyboards.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
3

I don't know when it was introduced, it may well have been there from the beginning, but I believe the reason it's there is as an alternative to && for people with restricted character sets i.e. where they don't actually have the ampersand character.

There are many others too eg. and_eq, or, compl and not to name just a selection.

Troubadour
  • 13,334
  • 2
  • 38
  • 57