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++
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 !=
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.
You can use -fno-operator-names to disable this. Alternatively, you can name your std::string object something else!
There are several such alternatives defined in C++. You can probably use switches to turn these on/off.
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
They were added because some of those characters are difficult to type on some keyboards.
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.
Related
I'm used to the and and or keywords in C++. I've always used them and typing them is fast and comfortable for me. Once I've heard that these aliases are non-standard and may not work on all compilers. But I'm not sure of it, I don't really know if it's true.
Let's assume that I give someone my code, will he have problems compiling it?
Is it all right when I use and, or instead of &&, ||? Or are these keywords really non-standard?
P.S.I use the MinGW compiler.
They are in fact standard in C++, as defined by the ISO 14882:2003 C++ standard 2.5/2 (and, indeed, as defined by the 1998 edition of the standard). Note that they are built into the language itself and don't require that you include a header file of some sort.
However, they are very rarely used, and I have yet to see production code that actually uses the alternative tokens. The only reason why the alternative tokens exist in the first place is because these characters on some keyboards (especially non-QWERTY ones) were either nonexistent or clumsy to type. It's still in the standard for backwards compatibility.
Even though they are standard, I highly recommend that you don't use them. The alternative tokens require more characters to type, and the QWERTY keyboard layout already has all the characters needed to type out C++ code without having to use the alternative tokens. Also, they would most likely bewilder readers of your code.
2.5/2 Alternative tokens
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 | != |
+--------------+-----------+
These keywords ARE standard and are described in section 2.5 of the standard. Table 2 is a table of these "alternative tokens". You can use them all you want, even though everyone will hate you if you do.
They are standard in the new c++0x standard. Up-to-date modern compilers should recognise them, although I don't believe they are obliged to yet. Whatever floats your boat, I assume.
they're standard C++, but with older compilers and possibly also with MSVC 10.0 (i haven't checked) you may have to include a special header, [isosomethingsomething.h]
cheers & hth.,
I have always messed up ^ (xor) and the ~ (two complement) operators. With the alternative tokens (that I believe should be primary ones) there is no question about what they do, yes, I agree with former posters that the textual ones are much more descriptive.
There is another possible messup using the digraphs, it is possible to forget one of the characters in ||, && that will cause subtle bugs and strange behaviours.
With the textual operators, it is much harder to make such a mistake.
I believe what I mentioned above are real valid arguments to improve code safety and clarity. Most C++ programmers SHOULD in my opinion try to get used to the textual operators in favor of the old cryptic ones.
I am surprised that so few programmers know about them. These operators should have taken over long time ago as I see it.
Wow, i've been using and looking at many C++ code examples for years.. and never, until now, knew about these so I guess that means most people don't use them. So, for the sake of consistency (if you plan on working in group projects etc) it's probably best to make a habit of using && and ||.
It's syntactically valid, given those are required alternative tokens.
In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling.
However, some tokens are used for more than just logical or bitwise operators. So one can see the idiosyncratic:
auto& foo(auto and T) { // C++20 forwarding reference
return T;
}
Or even
auto& foo(auto bitand T) { // lvalue reference
return T;
}
That's gonna make one scratch their head for a while.
Section 2.5 of the ISO/IEC 14882:1998 standard (the original C++ standard) says:
§2.5 Alternative tokens [lex.digraph]
1 Alternative token representations are provided for some operators and punctuators16).
2 In all respects of the language, each alternative token behaves the same, respectively, as its primary token,
except for its spelling17). The set of alternative tokens is defined in Table 2.
16) These include “digraphs” and additional reserved words. The term “digraph” (token consisting of two characters) is not perfectly
descriptive, since one of the alternative preprocessing tokens
is %:%: and of course several primary tokens contain two characters.
Nonetheless, those alternative tokens that aren’t lexical keywords are colloquially known as “digraphs”.
17) Thus the “stringized” values (16.3.2) of [ and <: will be different, maintaining the source spelling, but the tokens can otherwise be
freely interchanged.
Table 2—alternative tokens
_______________________________________________________________________________
alternative primary | alternative primary | alternative primary
<% { | and && | and_eq &=
%> } | bitor | | or_eq |=
<: [ | or || | xor_eq ^=
:> ] | xor ^ | not !
%: # | compl ~ | not_eq !=
%:%: ## | bitand & |
_______________________________________________________________________________
There is no discussion of 'if you include some header' (though in C, you need #include <iso646.h>). Any implementation that does not support the keywords or digraphs is not compliant with the 1998 edition, let alone later editions, of the C++ standard.
Obviously in regards to backward compatability the "and/or" keywords are not the issue. I would believe them to be the newer standard. It is just old programmers not understanding that some noob might have to be able to read the code and not want to look up what && means. Then again if any IT department is worth it's salt it will make the programmers conform to the standards of the company! That is my belief so (and/or) are futuristic and real possible standard going towards the future. && is backward compatable not(pun) (and/or).
I am not able to give seperate meaning to ^ using #define, like #define ^ +.
But where as I am able to give meaning to $ using #define , like #define $ +.
Could you please let me know how $ is different from ^?
On which rule of c++ standard this ^ is not allowed?
I am using VC++ 2012, Not tried with GCC or any other tool.
^ is an operator in C++. It is a bitwise XOR. Please read https://www.tutorialspoint.com/cplusplus/cpp_operators.htm
Operators cannot be "redefined" in this way, you need to overload them. C++ allows you to specify more than one definition for a function name or an operator in the same scope, which is called function overloading and operator overloading respectively (https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm
and https://en.wikibooks.org/wiki/C%2B%2B_Programming/Operators/Operator_Overloading#Bitwise_operators)
For bitwise operators, generally, they have a lower precedence than the arithmetic operators, so if ^ were to be overloaded for exponentiation, x ^ y + z may not work as expected.
For XOR the canonical form is: Type operator^(const Type &lhs, const Type &rhs); // Bitwise exclusive or, while for member function versions: Type &operator^=(const Type &rhs); // Assign exclusive or.
reference: http://articles.emptycrate.com/2009/10/12/nobody_understands_c_part_8_operator_overloading.html
The rules for names of preprocessor macros are the same as for identifiers: they can contain uppercase and lowercase letters, underscores, and numeric digits only. The first character in an identifier cannot be a digit.
That means it is not possible to use #define to redefine the meaning of operators like ^.
In standard C++, this also excludes identifiers containing a $. However, some compilers support identifiers containing $ as an extension.
^ is an operator you can use it to get input of strings with space like this scanf ("%[^\n]s,&x)...So you can only overload it and not define it as it has already been defined
This question already has answers here:
Why do these alternative operator representations exist
(2 answers)
Closed 7 years ago.
While looking for the operator list of C++ on Wikipedia, I found an article about operator synonyms:
C++ defines[6] keywords to act as aliases for a number of operators: and (&&), bitand (&), and_eq (&=), or (||), bitor (|), or_eq (|=), xor (^), xor_eq (^=), not (!), not_eq (!=), and compl (~). These can be used exactly the same way as the punctuation symbols they replace, as they are not the same operator under a different name, but rather simple token replacements for the name (character string) of the respective operator. This means that the expressions (a > 0 and flag) and (a > 0 && flag) have identical meanings. It also mean that, for example, the bitand keyword may be used to replace not only the bitwise-and operator but also the address-of operator, and it can even be used to specify reference types (e.g., int bitand ref = n). The ISO C specification makes allowance for these keywords as preprocessor macros in the header file iso646.h. For compatibility with C, C++ provides the header ciso646, inclusion of which has no effect.
Then I am wondering: Why do we need these operator synonyms? It would be nice if someone provide some use case.
All answers are here:
http://en.cppreference.com/w/cpp/language/operator_alternative
Basically, those are symbols which can not be represented in ISO 646 character codeset.
How can I force the shift\reduce conflict to be resolved by the GLR method?
Suppose I want the parser to resolve the conflict between the right shift operator and two closing angle brackets of template arguments for itself. I make the lexer pass the 2 consecutive ">" symbols, as separate tokens, without merging them into one single ">>" token. Then i put these rules to the grammar:
operator_name:
"operator" ">"
| "operator" ">" ">"
;
I want this to be a shift\reduce conflict. If I have the token declaration for ">" with left associativity, this will not be a conflict. So I have to remove the token precedence\associativity declaration, but this results in many other conflicts that I don't want to solve manually by specifying the contextual precedence for each conflicting rule. So, is there a way to force the shift\reduce conflict while having the token declared?
I believe that using context-dependent precedence on the rules for operator_name will work.
The C++ grammar as specified by the updated standard actually modifies the grammar to accept the >> token as closing two open template declarations. I'd recommend following it to get standard behaviour. For example, you must be careful that "x > > y" is not parsed as "x >> y", and you must also ensure that "foo<bar<2 >> 1>>" is invalid, while "foo<bar<(2 >> 1)>>" is valid.
I worked in Yacc (similar to Bison), with a similar scenario.
Standard grammars are, sometimes, called "parsing directed by syntax".
This case is, sometimes, called something like "parsing directed by semantics".
Example:
...
// shift operator example
if ((x >> 2) == 0)
...
// consecutive template closing tag example
List<String, List<String>> MyList =
...
Lets remember, our mind works like a compiler. The human mind can compile this, but the previous grammars, can't. Mhhh. Lets see how a human mind, would compile this code.
As you already know, the "x" before the consecutive ">" and ">" tokens indicates an expression or lvalue. The mind thinks "two consecutive greater-than symbols, after an expresion, should become a single shift operator token".
And for the "string" token: "two consecutive greater-than symbols, after a type identifier, should become two consecutive template closing tag tokens".
I think this case cannot be handled by the usual operator precedence, shift or reduce, or just grammars, but using ( "hacking" ) some functions provided by the parser itself.
I don't see an error in your example grammar rule. The "operator" symbol avoids confusing the two cases you mention. The parts that should be concern its the grammars where the shift operator its used, and the consecutive template closing tags are used.
operator_expr_example:
lvalue "<<" lvalue |
lvalue ">>" lvalue |
lvalue "&&" lvalue |
;
template_params:
identifier |
template_declaration_example |
array_declaration |
other_type_declaration
;
template_declaration_example:
identifier "<" template_params ">"
;
Cheers.
I've just read this nice piece from Reddit.
They mention and and or being "Alternative Tokens" to && and ||
I was really unaware of these until now. Of course, everybody knows about the di-graphs and tri-graphs, but and and or? Since when? Is this a recent addition to the standard?
I've just checked it with Visual C++ 2008 and it doesn't seem to recognize these as anything other than a syntax error. What's going on?
From the first ISO C++ standard C++98, this is described in 2.5/ Alternative tokens [lex.digraph]:
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 | alternative primary | alternative primary
--------------------+---------------------+--------------------
<% { | and && | and_eq &=
%> } | bitor | | or_eq |=
<: [ | or || | xor_eq ^=
:> ] | xor ^ | not !
%: # | compl ~ | not_eq !=
%:%: ## | bitand & |
So it's been around since the earliest days of the C++ standardisation process. The reason so few people are aware of it is likely because the main use case was for people operating in environments where the full character set wasn't necessarily available. For example (and this is stretching my memory), the baseline EBCDIC character set on the IBM mainframes did not have the square bracket characters [ and ].
MSVC supports them as keywords only if you use the /Za option to disable extensions; this is true from at least VC7.1 (VS2003).
You can get them supported as macros by including iso646.h.
My guess is they believe that making them keywords by default would break too much existing code (and I wouldn't be surprised if they are right).
To actually answer the question :
They were defined in the first C++ standard.
See the C++ standard. The committee draft #2 is freely available at ftp://ftp.research.att.com/dist/c++std/WP/CD2/body.pdf, although it's non-authoritative, out-of-date, and partially incorrect in a few places. Specifically, in section 2.5, Alternative Tokens, the following are defined:
Alternative Primary
<% {
%> }
<: [
:> ]
%: #
%:%: ##
and &&
bitor |
or ||
xor ^
compl ~
bitand &
and_eq &=
or_eq |=
xor_eq ^=
not !
not_eq !=
Though honestly, I've never seen any of them ever used except for and, or, and not, and even then, those are rare. Note that these are NOT allowable by default in plain C code, only in C++. If you want to use them in C, you'll have to either #define them yourself as macros, or #include the header <iso646.h>, which defines all of the above except for <% >% <: :> %: %:%: as macros (see section 7.9 of the C99 standard).
Although the question is old, I'd want to provide it with more or less full answer:
Alternative tokens were already a part of the currently withdrawn C++98 (ISO/IEC 14882:1998, which, I believe, was the first ISO standard for C++).
While not a proof in itself (and I don't own a copy of ISO for c++98), here's a link - see C++ section.
As mentioned in the other answers, MSVC compiler is violating [lex.digraph] section of the standard when /Za flag is not specified.
You may be surprised to learn about the rest of them:
and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq
List from C++ Keywords.
I believe recent versions of GCC support these keywords.
The GNU compiler g++ has them, but I don't know about MS VC++.
You can get the same functionality by putting this at the top of your code file.
#define and &&
#define bitor |
#define or ||
#define xor ^
#define compl ~
#define bitand &
#define and_eq &=
#define or_eq ^=
#define xor_eq ^=
#define not !
#define not_eq !=
Though this is kinda hackish, it should work.
They are in the working paper for the new C++ standard, on page 14:
C++ Standard