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
Related
I have overloaded the 2D subscript operator in one of my classes. And for that I use the -std=c++23 option to compile the program.
Now when calling this operator, GCC complains:
warning: top-level comma expression in array subscript changed meaning in C++23 [-Wcomma-subscript]
331 | m_characterMatrix[ x1, y1 ] = ch.value( );
| ~~~~~~~~~~~~~~~~~^
So what is this warning for? Should I take it seriously?
The warning is there because the compiler's assumption is that you might have been expecting the pre-C++23 behaviour - that is, the "traditional" comma operator evaluation.
(While common sense would clearly indicate that you meant to use your overload and there is no problem, computer programs don't possess common sense.)
You can disable that warning with -Wno-comma-subscript.
Using an unparenthesized comma expression as second (right) argument
of a subscript operator is deprecated.
For example, a[b, c] is deprecated and a[(b, c)] is not.
An unparenthesized comma expression cannot be second (right) argument of a subscript operator. For example, a[b, c] is either ill-formed or equivalent to a.operator[](b, c).
Parentheses are needed to for using a comma expression as the subscript, e.g., a[(b, c)].
Via: https://en.cppreference.com/w/cpp/language/operator_other
So yes, I think you should add parens inside operator[] to have old behaviour
if(a .feq. 5.0_dp) then **** if(a .fne. 5.2_dp) then ***
I come across some codes like this. What does the .feq. or .fne. mean? Is it "=" or "\ =" ?
In Fortran, operators (unary or binary) can take this form, a string of letters (up to 63) with a . at either end. So .feq. and .fne. are operators.
We'll also see operators such as .not., .eq. and so on.
Some operators, such as the two just mentioned, are standard intrinsic operators, some may be non-standard intrinsic operators, and we can even have user defined operators.
.feq. and .fne. are not (Fortran 2018) standard intrinsic operators. They may be non-standard intrinsic operators, but most likely they are user-defined. As they are not standard operators, we cannot say what they do (although as veryreverie comments, we can make reasonable guesses).
You will need to read the documentation for the project (or compiler, for the case of non-standard intrinsic operators), or you can look at the available source code.
How will you find what a user-defined operator does? For .feq. for example you should find an interface block with the OPERATOR(...) syntax:
interface operator (.feq.)
...
end interface operator (.feq.)
Inside that interface block you'll find mention of one or more specific functions, much as you would with other generic functions. Check these functions until you find one with the right number of arguments (one for a unary operator, two for a binary) of the right type (first argument matching the one after the .feq. if it's unary; or to the left if it's binary, with the second argument the right). You can then see what this function does.
You may also find your IDE or other tools will tell you how the operator is resolved.
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.
The question comes when I tried to make a macro like this:
#define OP1(a,b,op) (a) op (b)
then I was wondering why not also put op into parentheses, as it is also a macro parameter.
I then find I cannot even have this:
1 (+) 1;
otherwise there will be error:
error: expected primary-expression before ')' token
Can anyone tell me where is the rule saying operator cannot be in parentheses? I really cannot find it. Thank you.
§ 7.6.6 (expr.add) defines "additive expressions" as:
additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression
No parens around the operator allowed.
There actually isn't any rule that says an operator should not be in parenthesis. But there is a rule that states that, "for a binary operator like +, the value on either sides of the operator must be valid operands like 5, 5.2".
So the expression (+) to the compiler means you are adding two parentheses (left paren, plus, right paren) together which is not supported by the language.
Putting macro parameters in parenthesis is good practice of course, but there is actually no need for putting the operator in this case inside parenthesis as there is no way of passing a complicated operator expression so you can rest assured that your macro will always work.
In programming, as in mathematics, the parentheses are used to override the operators precedence.
Without parentheses, 2 + 3 * 4 is evaluated as 2 + (3 * 4) because the multiplication (*) has a higher precedence than the addition (+). One can use parentheses to force the addition of 2 and 3 happen before the multiplication (of the result) by 4 by placing them around the addition operator and its operands as (2 + 3) * 4.
Both 3 * 4 and 2 + 3 in the expressions above are valid expressions.
+ in the expression 1 (+) 2 is not a valid expression. More, assuming the parentheses contain a valid sub-expression, the entire expression is invalid because it is just a list of values without operators to connect them into an expression.
Even more, this is also not the way you learned in school to write mathematical expressions.
Back to your #define, to avoid hidden errors and headache (due to the operators precedence) you should always enclose the expanded value of such a macro into parentheses like this:
#define OP1(a,b,op) ((a) op (b))
I have read this question and I want to add to it that what are the things that can not be done using the comma operator. This has confused me a lot, as I can do this:
int arr[3];
arr[0]=1,arr[1]=2,arr[2]=3;
But when I do:
int arr[3],arr[0]=1,arr[1]=2,arr[2]=3;
It gives me a compiler error.
I want to ask that what are the limitations of the comma operator in real practice?
One thing to realize is that not all uses of a comma in C are instances of the comma operator. Changing your second example to be a syntactically declaration:
int a0=1,a1=2,a2=3;
the commas are not operators, they're just syntax required to separate instances of declarators in a list.
Also, the comma used in parameter/argument lists is not the comma operator.
In my opinion the use of the comma operator is almost always a bad idea - it just causes needless confusion. In most cases, what's done using a comma operator can be more clearly done using separate statements.
Two exceptions that come to mind easily are inside the control clauses of a for statement, and in macros that absolutely need to cram more than one 'thing' into a single expression, and even this should only be done when there's no other reasonable option).
You can use the comma operator most anywhere that an expression can appear. There are a few exceptions; notably, you cannot use the comma operator in a constant expression.
You also have to be careful when using the comma operator where the comma is also used as a separator, for example, when calling functions you must use parentheses to group the comma expression:
void f(int, bool);
f(42, 32, true); // wrong
f((42, 32), true); // right (if such a thing can be considered "right")
Your example is a declaration:
int arr[3],arr[0]=1,arr[1]=2,arr[2]=3;
In a declaration, you can declare multiple things by separating them with the comma, so here too the comma is used as a separator. Also, you can't just tack on an expression to the end of a declaration like this. (Note that you can get the desired result by using int arr[3] = { 1, 2, 3 };).