According to the C Standard (6.5.2 Postfix operators) the subscript operator is defined the following way
postfix-expression [ expression ]
So before the square brackets there shall be a postfix expression.
In this expression statement
x = -1[p];
there is used the postfix expression 1
(that is at the same time a primary expression), the postfix expression 1[p]
(that is the subscript operator) and the unary operator -
Take into account that when the compiler splits a program into tokens then integer constants are considered as tokens themselves without the minus. minus is a separate token.
So the statement can be rewritten like
x = -( 1[p] );
because a postfix expression has a higher priority than an unary expression.
Let's consider at first the postfix sub-expression 1[p]
According to the C Standard (6.5.2.1 Array subscripting)
2 A postfix expression followed by an expression in square brackets []
is a subscripted designation of an element of an array object. The
definition of the subscript operator [] is that E1[E2] is identical to
(*((E1)+(E2))). Because of the conversion rules that apply to the
binary + operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an integer,
E1[E2] designates the E2-th element of E1 (counting from zero).
So this sub-expression evaluates like *( ( 1 ) + ( p ) )
and is the same as *( ( p ) + ( 1 ) ).
Thus the above statement
x = -1[p];
is equivalent to
x = -p[1];
and will yield -3
, because the pointer p
points to the second element of the array due to the statement
int *p = &array[1];
and then the expression p[1]
yields the value of the element after the second element of the array. Then the unary operator -
is applied.
-(p[1])
which is the same as-(array[2])
. – Singaporea[5] == 5[a]
. But if you haven't also memorized C's less-than-intuitive precedence rules, or if you don't remember that C treats-1
as an application of the unary minus operator (instead of treating it as a single token and an intrinsically negative constant), you might be fooled into thinking that-1[p]
is the same asp[-1]
rather than-(p[1])
. – Fractionate-p[1]
would try to negate a pointer ... – Rya[5] == 5[a]
one as a dup, too, but it really only covers half of this question. I'd say the surprising precedence here is equally significant. – Masticatory-(1[p])
or-p[1]
if it wasn't obvious. – Ferdy