Reputation: 34608
#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]
?
Upvotes: 34
Views: 10571
Reputation: 1051
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
Upvotes: 2
Reputation: 7157
-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]
.
Upvotes: 132
Reputation: 16117
-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)))
Upvotes: 18
Reputation: 311038
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]
Upvotes: 68