msc
msc

Reputation: 34608

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]?

Upvotes: 34

Views: 10571

Answers (4)

Chandrahas Aroori
Chandrahas Aroori

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

Chris Jefferson
Chris Jefferson

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

nalzok
nalzok

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

Vlad from Moscow
Vlad from Moscow

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

Related Questions