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]).a[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-1as 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]).-p[1]would try to negate a pointer ...a[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.