Given below is a C code snippet with str initialized to "face":   
char *str = "face";
printf("%d\n", -2[str]);
Given below is a C code snippet with str initialized to "face":   
char *str = "face";
printf("%d\n", -2[str]);
 
    
     
    
    First, we need to parse the expression in question: We have two operators in -2[str] - a subscript operator [] and a unary minus operator -. Subscript operator has higher precedence than unary minus, so printf prints a negation of 2[str]*.
There are many Q&As explaining that 2[str] is the same as str[2], so I am not going to repeat the explanation; you can read about it in this Q&A.
Finally, the value of str[2] is 'c', which represents code of 99 on your system. Negation is applied to that value, so that is how -99 gets printed.
* Note that - is not part of an integer constant, because in C integer constants do not include sign.
 
    
    The code in the question is:
char *str = "face";
printf("%d\n", -2[str]);
Let's be clear: this is horrid, and anyone writing that code should be made to rewrite it.
There are two parts to the confusion when approaching this:
a[i] == i[a]?-2[str] evaluated?The linked question covers (1) extensively. Read it.
To address the second part, consider an alternative program:
#include <stdio.h>
int main(void)
{
    char data[] = "XYZface";
    char *str = &data[3];
    printf("[%s] %d %d %d (%c)\n", str, -2[str], -(2[str]), (-2)[str], (-2)[str]);
    return 0;
}
This outputs:
[face] -99 -99 89 (Y)
Why?  The -2[str] notation is equivalent to -str[2] (you have read the linked Q&A, haven't you?) and not str[-2], because there are no negative literal numbers.
Read C11 §6.4.4.1 Integer constants: there are no minus signs in there.  When you write -2, you have a unary minus operator and a literal 2.  Mostly, that's the same as negative two, but not when mixed with a higher priority operator such as subscripting.  The §6.5.2 Postfix operators such as subscripting have higher priority than the §6.5.3 Unary operators such as negation.
Let's also be clear: there is no undefined behaviour in the question's code (or mine, I trust).  Technically, the value for letter 'c' (+99) is implementation-defined, but there are few extant systems where the integer value of 'c' is not 99 (but see EBCDIC for a code set where the answer would be different).
 
    
    Lets dissect:
-2[str]
is
-(2[str])
because of operator precedence. Note that the -2 is not directly an integer literal; 2 is and it can receive the unary operator -, but before that happens, the [] operator is applied.
Next step is
-(str[2])
Because (a well known if curious fact) a[i]==i[a].  
-('c')
Because of the format string %d, this is seen as a negative int, with the absolute value of the ASCII value of 'c'.
-(99)
-99
(This is of course a compilation of know-how by several commenters: Jonathan Leffler, StoryTeller and a little by myself.)
 
    
     
    
    As explained in the comments the code is working like this:
-(2[str]) => -(*(2 + str)) => -str[2]
As str[2] is 'c', whose ASCII value is 99. So the output is -99.
Thanks, storyteller for clearing this out.
