3

Here are 2 samples of code:

int k,j=1;
int x[4]={5,14,25,47};
k = x[j] + ++j;
printf("%d, %d",j,k);

A warning is displayed - "operation on 'j' may be undefined" But the output is : 2, 16

Then I tried this:

int k,j=1;
int x[4]={5,14,25,47};
k = x[j] +++j;
printf("%d, %d",j,k);

This does not give any warning but the output is a little confusing. Output- 1,15 Why is j not getting incremented in the 2nd case?

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 5
    Note the statement in your first snippet invokes Undefined Behaviour: `k = x[j] + ++j;` both uses and updates `j` without an intervening sequence point. – pmg Aug 09 '20 at 10:14

2 Answers2

8
k = x[j] +++j;

is the same as

k = (x[j]++) +j;

Also, k = x[j] + ++j is undefined behavior, because the evaluation order of addition is not defined. Apart from the fact that the compiler is allowed to produce anything, both of these two snippets are equally sound interpretations of that line:

j++;
k = x[j] + j;

and

j++;
k = x[j-1] + j;

In general, avoid being "smart". If you're not 100% sure what you're doing, don't use ++ and -- in more complex statements. Do the increment or decrement on a separate line before or after. That will save you tons of trouble. For instance, can you without any doubt and without googling it say exactly what

while(*str++) { 
    /* Do something */ 
} 

means? IMHO it's clearer with

while(*str) { 
    str++; 
    /* Do something */ 
} 

Sure it costs a line, and reducing the number of lines can be a good thing, but in this case I think it's better to play it safe. In this particular case you can also make it clearer with parenthesis: *(str++) if you prefer, but I think you see my point.

I actually made an answer where this was the actual problem: https://stackoverflow.com/a/56522806/6699433

klutt
  • 30,332
  • 17
  • 55
  • 95
3

A C program is parsed as a sequence of tokens, such as int, +, ++, and ->. When the source text contains +++, this could be the tokens + and ++ or the tokens ++ and +. A rule in C 2018 6.4 4 tells us which:

If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token…

Thus, in +++, the longest token that could be next is ++, so that is taken, leaving + for the next token. So x[j] +++j; is parsed as x [ j ] ++ + j ;.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312