Why this weird code works? - c++

I got the this:
int main(){
int Array[] = { 10, 20, 30 };
cout << -2[Array] << endl;
system("Pause");
return 0;
}
The output is:
-30
I want to know why the output is -30 and why causes this undefined behavior?
does anyone knows?

-2[Array] is parsed as -(2[Array]), since subscripting has higher precedence than unary minus.
Now, 2[Array] is just a weird way to write Array[2], so you get -Array[2], i.e. -30. No undefined behavior is involved in the whole expression.

This is fairly simple.
First, let's analyse the expression:
-2[Array]
is
-(2[Array])
Now a[b] is *(a+b) and since addition is commutative this is also *(b+a) i.e. Array[2].
Array[2] is 30; -Array[2] is -30. Thus, -2[Array] is also -30.
I sincerely hope you do not intend to use this in production code.

In C++, the following statement is true:
a[5] == 5[a]
This is because the syntax using [] is converted to:
*(a + 5)
E.g.
a[5] == *(a + 5)
Which means that
5[a] == *(5 + a)
Thus the notation -2[Array] is converted to - *(2 + Array).

It applies the unary operator (-, minus sign) to pointer incremented by the value outside of [] thus: - *(2 + Array). You can check it out by removing the minus sign, thus applying + unary operator. I would NOT recommend using this syntax.

Related

Why isn't arr[-2] equivalent to -2[arr]?

#include <iostream>
using namespace std;
int main()
{
int arr[3] = { 10, 20, 30 };
cout << arr[-2] << endl;
cout << -2[arr] << endl;
return 0;
}
Output:
4196160
-30
Here arr[-2] is out of range and invalid, causing undefined behavior.
But -2[arr] evaluates to -30. Why?
Isn't arr[-2] equivalent to -2[arr]?
-2[arr] is parsed as -(2[arr]). In C (and in C++, ignoring overloading), the definition of X[Y] is *(X+Y) (see more discussion of this in this question), which means that 2[arr] is equal to arr[2].
The compiler parses this expression
-2
like
unary_minus decimal_integer_literal
That is definitions of integer literals do not include signs.
In turn the expression
2[arr]
is parsed by the compiler as a postfix expression.
Postfix expressions have higher precedence than unary expressions. Thus this expression
-2[arr]
is equivalent to
- ( 2[arr] )
So the unary minus is applied to the lvalue returned by the postfix expression 2[arr].
On the other hand if you wrote
int n = -2;
and then
n[arr]
then this expression would be equivalent to
arr[-2]
-2[arr] is equivalent to -(2[arr]), which is equivalent to -arr[2]. However, (-2)[arr] is equivalent to arr[-2].
This is because E1[E2] is identical to (*((E1)+(E2)))
The underlying problem is with operator precedence. In C++ the [], ie the Subscript operator hold more precedence (somewhat akin to preferance) than the - unary_minus operator.
So when one writes,
arr[-2]
The compiler first executes arr[] then - , but the unary_minus is enclosed within the bounds of the [-2] so the expression is decomposed together.
In the,
-2[arr]
The same thing happens but, the compiler executes 2[] first the n the - operator so it ends up being
-(2[arr]) not (-2)[arr]
Your understanding of the concept that,
arr[i] i[arr] and *(i+arr) are all the same is correct. They are all equivalent expressions.
If you want to write in that way, write it as (-2)[arr]. You will get the same value for sure.
Check this out for future referance :http://en.cppreference.com/w/cpp/language/operator_precedence

c++ spaces in operators , what are the rules

Does spaces have any meaning in these expressions:
assume:
int a = 1;
int b = 2;
1)
int c = a++ +b;
Or,
2)
int c = a+ ++b;
When I run these two in visual studio, I get different results. Is that the correct behavior, and what does the spec says?
In general, what should be evaluated first, post-increment or pre-increment?
Edit: I should say that
c =a+++b;
Does not compile on visual studio. But I think it should. The postfix++ seems to be evaluated first.
Is that the correct behavior
Yes, it is.
Postfix ++ first returns the current value, then increments it. so int c = a++ +b means compute the value of c as the sum between current a(take the current a value, and only after taking it, increment a) and b;
Prefix ++ first increments the current value, then returns the value already incremented, so in this case, int c = a+ ++b means compute c as the sum between a and the return of the next expression, ++b, which means b is first incremented, then returned.
In general, what should be evaluated first, post-increment or
pre-increment?
In this example, it is not about which gets evaluated first, it is about what each does - postfix first returns the value, then increments it; prefix first increments the value, then returns it.
Hth
Maybe it helps to understand the general architecture of how programs are parsed.
In a nutshell, there are two stages to parsing a program (C++ or others): lexer and parser.
The lexer takes the text input and maps it to a sequence of symbols. This is when spaces are handled because they tell where the symbols are. Spaces really matter at some places (like between int and c, to not confuse with the symbol intc) but not others (like between a and ++ because there is no ambiguity to separate them).
The first example:
int c = a++ +b;
gives the following symbols, each on its own row (implementations may do this in slightly different ways of course):
int
c
=
a
++
+
b
;
While in the other case:
int c = a+ ++b;
the symbols are instead:
int
c
=
a
+
++
b
;
The parser then builds a tree (Abstract Syntax Tree, AST) out of the symbols and according to some grammar. In particular, according to the C++ grammar, + as an addition has a lower precedence than the unary ++ operator (regardless of postfix or prefix). This means that the first example is semantically the same as (a++) + b while the second is like a+ (++b).
For your examples, the ASTs will be different, because the spaces already lead to a different output at the lexer phase.
Note that spaces are not required between ++ and +, so a+++b would theoretically be fine, but this is not recommended for readability. So, some spaces are important for technical reasons while others are important for us users to read the code.
Yes they should be different; the behaviour is correct.
There are a few possible sources for your confusion.
This question is not about "spaces in operators". You have different operators. If you were to remove the space, you would have a different question. See What is i+++ increment in c++
It's also not about "what should be evaluated first, post-increment or pre-increment". It's about understanding the difference between post-increment and pre-increment.
Both increment the variable to which they apply.
But the post-increment expression returns the value from before the increment.
Whereas the pre-increment expression returns the value after the increment.
I.e.
//Given:
int a = 1;
int b = 2;
//Post-increment
int c = a++ +b; =>
1 + 2; (and a == 2) =>
3;
//Pre-increment
int c = a+ ++b; =>
1 + 3; (and b == 3) =>
4;
Another thing that might be causing confusion. You wrote: a++ +b;. And you may be assuming that +b is the unary + operator. This would be an incorrect assumption because you have both left and right operands making that + a binary additive operator (as in x + y).
Final possible confusion. You may be wondering why:
in a++ +b the ++ is a post-increment operator applied to a.
whereas in a+ ++b it's a pre-increment operator applied to b.
The reason is that ++ has higher precedence than the binary additive +. And in both cases it would be impossible to apply ++ to +.

C++ pointer . I want to know about the logic

i have a question on pointer concept which i could not find a logical answer to
#include<conio.h>
#include<iostream.h>
void main()
{
int arr[10];
clrscr();
cout<<*arr+5 - *arr+3;
getch();
}
even if i assign arr[0]=10; (or any other value)
the compiler gives answer 8 but how . I can not see(understand) how operator precedence and associativity does solve it.
I will be grateful to you.
Because of *arr - *arr is 0 and 5 + 3 is 8.
The result you may be expecting is the result of:
cout<<(*arr+5) - (*arr+3);
The compiler gives answer 8 because that operation is simply equivalent to: (*arr - *arr) + 5 + 3 = 8. If you want to add the scalar to the pointer and then get the referenced value, you have to use parentheses *(arr+5).
If you look at the precedence table, for example here:
http://en.cppreference.com/w/cpp/language/operator_precedence
then you'll notice that the dereference operator (*) has higher priority than addition/subtraction (+/-) operators (they are in group no. 3 and 6 respectively). This is why the first operation that is performed is getting the value that the arr variable is pointing to, i.e. this part:
*arr
After this, the addition/subtraction is performed. The value that arr is pointing to doesn't matter since it gets reducted anyway.
This is how you should read this expression:
(*arr) + 5 - (*arr) + 3
and (*arr) - (*arr) is 0, no matter what value it points to.
EDIT: What I've written above is apparently true in your case and your compiler, but look at the #Konrad Rudolph comments to this answer.
And, if you are curious, how the compiler knows if, for example, the '*' should be treated as multiplication or dereference operator: it resolves this problem by looking at the number of arguments - if there's only one, than it's derefence, and if there are two, then it's multiplying.

Why the addtion of ++overloaded operation results into unexpted values?

See the code
#include<iostream.h>
#include<conio.h>
class A{
private:
int i;
public:
A()
{
i=10;
}
A operator++(int)
{
A tmp=*this;
i +=1;
return tmp;
}
display()
{
cout<<i;
}
};
int main()
{
A a,b;
b=a++ + a++;
cout<<endl<<b<<"\t"<<a;
return 0;
}
For the statement b = a++ + a++, the expected value we think will be 20,
But the above statement resulted into 21.
How?
Kindly help me out.
According to cppreference, your code is equals to b = (a++) + (a++)
So, computing it, we have:
a = 10;
tmp1 = a++;//tmp1 = 10, a = 11
tmp2 = a++;//tmp2 = 11, a = 12
b = tmp1 + tmp2 // 10 + 11 = 21
Also remember that constructions like b = a++ + a++; are very poor readable, so you should always use brackets, also it's always a good idea to avoid using increments and decrements like a++ in complex expressions. Readability is much better than showing that you know operator priorities.
As Charles pointed out ++ called on A object are function calls. Thus you first increment i from 10 to 11 and return 10, then in the second call you increment i from 11 to 12 and return 11. The you add 10 and 11 ending up with 21.
The first call increments a to 11 and returns 10. The second call increments a to 12 and returns 11. Sounds like 21 is correct.
That said, the order of evaluation (which ++ is "the first call") is unspecified (thanks JD), so using it twice in the same expression is generally not a good idea.
I shall render my answer in the form of a simple comparison.
Your code is:
b = a++ + a++;
I think you rather confused it with:
b = a + (a++)++;
Overloaded operators are just functions with funny names. They don't neccesarily behave the same as built-in ones. If you're tempted to do the same expression with an object of built-in type - don't, the behaviour would be undefined.
You haven't shown the definition of operator+ for A - I'll asume it's a free function. The expression b = a++ + a++; can then be rewritten as
b = operator+( a.operator++(0), a.operator++(0) );
Hope that helps make things clearer.
The two calls to postfix increment are indeterminately sequenced - that means we can't know which one will be called first. It doesn't matter in your case, since they're both called on the same object, but don't rely on any particular order - it need not be consistent, even during the same execution of the program.

What does the operation c=a+++b mean?

The following code has me confused
int a=2,b=5,c;
c=a+++b;
printf("%d,%d,%d",a,b,c);
I expected the output to be 3,5,8, mainly because a++ means 2 +1 which equals 3, and 3 + 5 equals 8, so I expected 3,5,8. It turns out that the result is 3,5,7. Can someone explain why this is the case?
It's parsed as c = a++ + b, and a++ means post-increment, i.e. increment after taking the value of a to compute a + b == 2 + 5.
Please, never write code like this.
Maximal Munch Rule applies to such expression, according to which, the expression is parsed as:
c = a++ + b;
That is, a is post-incremented (a++) and so the current value of a (before post-increment) is taken for + operation with b.
a++ is post incrementing, i.e. the expression takes the value of a and then adds 1.
c = ++a + b would do what you expect.
This is an example of bad programming style.
It is quite unreadable, however it post increments a so it sums the current value of a to b and afterwards increments a!
a++ gets evaluated after the expression.
c = ++a + b; would give you what you thought.
The post increment operator, a++, changes tge value of a after the value of a is evaluated in the expression. Since the original value of a is 2, that's what's used to compute c; the value of a is changed to reflect the new value after the ++ is evaluated.
a++ + b ..it gives the result 7 and after the expression value of a is update to 3 because of the post increment operator
According to Longest Match rule it is parsed as a++ + +b during lexical analysis phase of compiler. Hence the resultant output.
Here c= a+++b; means c= (a++) +b; i.e post increment.
In a++, changes will occur in the next step in which it is printing a, b and c.
In ++a, i.e prefix-increment the changes will occur in the same step and it will give an output of 8.