tushar pahuja
tushar pahuja

Reputation: 77

How is the following code giving the output as -99?

Given below is a C code snippet with str initialized to "face":

char *str = "face";
printf("%d\n", -2[str]);

Upvotes: 0

Views: 246

Answers (4)

Jonathan Leffler
Jonathan Leffler

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:

  1. Why is a[i] == i[a]?
  2. How is -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

Yunnosch
Yunnosch

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Abhishek Keshri
Abhishek Keshri

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

Related Questions