Why does C++ need operator synonyms? [duplicate] - c++

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.

Related

Why write `!!x`, when `x` will do? [duplicate]

This question already has answers here:
Double Negation in C++
(14 answers)
What is the usage of "!!" (negating twice)? [duplicate]
(3 answers)
Confused by use of double logical not (!!) operator [duplicate]
(5 answers)
Closed 2 years ago.
I often see experienced programmers write !!x, even though the expected expression is a Boolean (i.e., zero or not zero) and not an integer.
For example, a line from boost:
BOOST_ASSERT(!!p); // where `p` is a pointer
What's the point of !!p when just p will do?
What I understand by a Boolean parameter is an expression converted to a value of integral type, and the value is compared against zero, explicitly or implicitly (with if or its ternary operator equivalent).
Thus, anything that takes a Boolean and expects only 0 or 1 is wrongly implemented, if my understanding of Boolean is correct.
For clarification: it's obvious that ! converts to bool; the question is explicitly asking for why.
By default, BOOST_ASSERT(expr) expands to assert(expr). That C++ assert function takes a scalar argument, not bool. Thus, your statement, "the expected expression is a boolean," is not correct.
Classes in C++ can implement operator bool(); the basic_stream classes are examples of such: assert(std::cin) will not work. The !! operator forces the use of std::cin::operator bool(), and bool after !! will be evaluated to int 0 or 1. This is shorter than assert(bool(std::cin)).
If I were a boost author, I would expand BOOST_ASSERT(expr) to assert(!!(expr)) - as is done for ( BOOST_LIKELY(!!(expr)) ? ((void)0) ).
Closely related to the question
Warnings.
Some compilers issue warnings.
Overflow of the integer storing the Boolean.
I'll just quote the comment mentioning the behaviour
The compiler would treat the values the same either way if it's only used as an operand to an if or &&, but using !! may help on some compilers if if (!!(number & mask)) gets replaced with bit triggered = !!(number & mask); if (triggered); on some embedded compilers with bit types, assigning e.g. 256 to a bit type will yield zero. Without the !!, the apparently-safe transformation (copying the if condition to a variable and then branching) won't be safe.
Related
Some consider defining operator bool() to be "unsafe". And to have an idiomatical way to convert to bool, they define bool operator !().
So writing !!obj is to support such users. And it doesn't even hurt to do so!

In C (also C++), how '&' operator works as both address operator and bitwise operator ? As operator overloading is not supported by C

The operator '&' can be used in both of following way int a; scanf("%d",&a);
and printf("%d",1&2).
But different behaviour (for first as address operator and second time as bit-wise operator).
I know operator overloading is not there in C. Then how it works ?. Also highlight for c++.
I know operator overloading is not there in C.
This is incorrect. a + b performs integer addition if a and b are integers, floating-point addition of a and b are floating-point numbers, and pointer arithmetic if a or b is a pointer.
C has operator overloading built into the language. It does not support custom operator overloading defined by the program.
In the case of & being an operator for taking an address and for performing a bitwise AND, the distinction is made by the language grammar. The & for taking an address can appear only applied to a cast-expression in the grammar. The & for bitwise AND can appear only after an AND-expression and before an equality-expression. These “tokens” (cast-expression, AND-expression, and equality-expression) may be unfamiliar to you, but they are formally defined in the grammar for the C language, and, as the compiler is parsing source code, it recognizes the structure of expressions and matches the source code to the tokens of the grammar. This is also true for C++ except for a minor technical difference: In C++, one of the tokens is and-expression instead of AND-expression.
The definition of the grammar is such that recognition of these tokens always uniquely distinguishes how the & operator is being used.
In "C" language, operators have different meaning when they are used as prefix to expression, suffix to expression or "infix" (between two expressions).
Consider '*', which performs multiplication as 'infix' operator, and pointer indirection when used as a prefix. Similarily, the '-' operator, which performs subtraction as 'infix' operator, and negation when used as a prefix.
Basically, it's not about overriding, it if the operator appears between two expressions, or as a prefix to a single expression.
In the same way, The "C" compiler knows if the '&' is bit-wise and, or address-of, based on it's position is the expression: If it is between two expressions, it's the AND, if it is before an expression, it is 'address-of'.
See https://en.wikipedia.org/wiki/Infix_notation about infix.
C does not support operator overloading (beyond what it built into the language).
As you can see in this Wikipedia Operators in C
The Address-of ("address of a") "&a" is defined as R* K::operator &();
whereas
The Bitwise AND "a & b" is defined as R K::operator &(S b);
So basically the "&" operator has different meaning when used as a unary operator and as a binary operator operator. The same goes for various other operators like, "*" , "-", etc.
It has simple different meanings when applied to the lvalue (it the unary operator in this case) or when it is used in the math expression with two operands.
"The operator & can be used in both of following way int a; scanf("%d",&a); and printf("%d",1&2)."
Note that in the case of C++ you forgot another important third use. The & operator can also be used to declare references.
int x = 24;
int& r_x = x;
the language divides operators based on its operands first. In one category itself overloading can be in-built. Your example is about the first division. Address-of is a unary operator and bitwise-AND is a binary operator. when you write operator function in c++ you will see the difference of these two categories.
Operator overloading is inbuilt to languages. example simple arithmetic addition operator. it can work with simple one-byte integer data as well as float (significant & exponent). Basically it is there with maths. so while making C language, they just translated those into functionality. In C specification, you cannot find overloading as a keyword for this behavior. According to them, after formula expression, anything has to be expressed as different functions. Each function should be named based on the functionality that it offers. When C++ introduced an opportunity to create new types, operators with its basic n-nary form allowed to operate with new types. In a nutshell, C's philosophy was different.

Difference between "&&" and "and" operators [duplicate]

This question already has answers here:
Is it okay to use "and", "or" etc. instead of "&&", "||"?
(9 answers)
Are "not, and, or, not_eq.." part of the C++ standard? (And why might they be used or avoided in code?)
(5 answers)
Closed 5 years ago.
I saw alternative operators (like and, or, not etc.) when browsing cppreference.
They are alternatives to "normal" operators like &&, ||, ! etc.
I examined the assembly for code that uses && and and. Both versions generated the same assembly.
Code :
#include <iostream>
int n = 1;
int main()
{
// if(n > 0 && n < 5)
if(n > 0 and n < 5)
{
std::cout << "n is small and positive\n";
}
}
So my questions are:
What is the difference between the && and and operators?
Where and when do I use and over &&?
If there is no difference, then why does C++ introduce alternative operators (like and, or, not etc.)?
What is the difference between the && and and operators?
There is none1. The "alternative" aspect of these operators means that they can be used to construct the exact same expressions from a semantic perspective.
Where and when do I use and over &&?
This is largely a matter of preference. I'm too used to && to not use it, but can understand if someone finds and more readable.
why does C++ introduce alternative operators?
C++ was designed to be available on a variety of character sets and platforms. Trigraphs, like Bathsheba pointed out, are another example of such a feature. If a character set would not allow && to be written (say, because it simply didn't have the & character) then one can still get by with the alternative representation. Nowadays, it's largely moot.
1 Actually, upon further thinking, my answer to your first question can be refined. There is a slight lack of equivalence, pertaining to how tokens are parsed. && doesn't require a space to be parsed as a separate token, while and does. That means:
void foo(bool b1, bool b2) {
if(b1&&b2) { // Well formed
}
if(b1andb2) { // ill formed, needs spaces around `and`
}
}
and, or, not, &c. are examples of the alternative operators.
For the full list see http://en.cppreference.com/w/cpp/language/operator_alternative; the opening paragraph is a raison d'etre:
C++ (and C) source code may be written in any non-ASCII 7-bit
character set that includes the ISO 646:1983 invariant character set.
However, several C++ operators and punctuators require characters that
are outside of the ISO 646 codeset: {, }, [, ], #, \, ^, |, ~. To be
able to use character encodings where some or all of these symbols do
not exist (such as the German DIN 66003), C++ defines the following
alternatives composed of ISO 646 compatible characters.
If I were you I'd shy away from using them, much in the same way as you ought to shy away from using digraphs and trigraphs, even if the latter make for interview fun.
Trigraphs for example are explicitly discontinued from C++17. You might see and &c. being dropped in future standards too.

When did "and" become an operator in C++

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.

C++ and,or,not,xor keywords [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
The written versions of the logical operators.
I notice that C++ define keyword and, or, not, xor, and_eq, or_eq, not_eq and xor_eq as an alternative to &&, ||, !, ^, &=, |=, != and |=. and they're rarely used! What's wrong? Are they not portable?
They come from C AFAIR from times when it was not known what special symbols are on the keyboard. So to have portable language they were defined so anyone can use C even if they used keyboard with no &, |, or ^ (etc.).
Nowadays when QWERTY is a standard (with AZWERTY & co. as variations) it is no longer an issue.
PS. And of course for obfuscation code competitions ;)