Reputation: 77
Given below is a C code snippet with str
initialized to "face":
char *str = "face";
printf("%d\n", -2[str]);
Upvotes: 0
Views: 246
Reputation: 753625
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).
Upvotes: 4
Reputation: 26703
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.)
Upvotes: 3
Reputation: 726509
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.
Upvotes: 5
Reputation: 3234
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.
Upvotes: 1