0

I have a code

#include <stdio.h>
int main(){
    int y [10]; int i = 1;
    y[i] = i++;
    printf("y0: %d\n", y[0] );
    printf("y1: %d\n", y[1] );
    printf("y2: %d\n", y[2] );
}

I think that line

y[i] = i++; 

should work as y[1] = 1; and then set i to 2;

But y[1] has got some random value and y[2] is set to 1. Why?

fphilipe
  • 9,739
  • 1
  • 40
  • 52
Mateusz
  • 604
  • 8
  • 20
  • `++i` first increments the value of `i` and then returns an **lvalue**, so if the value of `i` is used then it will be the new incremented value. `i++` first returns an **rvalue** whose value is `i`, that is, the old value, and then increments `i` at an unspecified time before the next full-expression. – sharvil111 Nov 30 '15 at 12:40
  • If it looks dodgy, ( and y[i] = i++; does), and you only THINK it will work, why are you using it? Why did you not just split it up so that you KNOW how it works? I cannot understand why you would post such rubbi.. code here instead of taking the obvious, and easy, step of just fixing it. – Martin James Nov 30 '15 at 14:22

2 Answers2

3

You are in the domain of undefined behavior. On some compilers it might work, on other it might not.

The problem is that in the line

y[i] = i++;

i is evaluated twice and you can't assume if it's the expression before the assignment or after.

if i++ is evaluated first the expression result becomes 1. But it is incremented before y[i] gets evaluated. So i == 2 then creating a result of y[2] = 1; if i before the assignment is evaluated first then the result becomes y[1] = 1; i++;

changing this to will fix it of course:

y[i] = i;
i++;
Serve Laurijssen
  • 9,266
  • 5
  • 45
  • 98
  • Yes, I know that it is udefined behavior but if I got: y[2]=1 it is not possible. Because if firstly done i++ and then indexed array it would be y[2]=2, if firstly took left side it would be y[1]=2 or y[1]=1 – Mateusz Nov 30 '15 at 12:39
  • @dsadsadsadsad No that's not undefined behaviour . It's not similar case as `i=i++` . – ameyCU Nov 30 '15 at 12:40
  • @dsadsadsadsad Undefined behavior means _there is no expected, predictable behavior_. The program might as well crash, as print some sort of output, or do nothing at all. Etc etc. Not to be confused for unspecified behavior, where the program will behave in a certain way which we can't know in advance, but at least it won't halt and catch fire. – Lundin Nov 30 '15 at 12:45
  • @Lundin Why is it undefined behaviour ? – ameyCU Nov 30 '15 at 12:45
  • @ameyCU Because `i` is accessed twice between two sequence points, for other purposes than to determine the value to store inside `i`. See the linked duplicate. – Lundin Nov 30 '15 at 12:47
  • @Lundin But it is changed only 1 time between sequence points . As I mentioned previously , this is not similar to `i=i++;` which is described in that link . I think it is rather unspecified . – ameyCU Nov 30 '15 at 12:48
  • 1
    @ameyCU The number of side effects is not the only thing that can make an expression UB. There are two sentences in the standard (6.5). You refer to the first one: `If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.` But directly after that sentence follows: `If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.` – Lundin Nov 30 '15 at 12:52
  • 1
    @ameyCU C99 stated this much clearer imo: `Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored. 73)` Note 73) gives a nearly identical example to this one: `This paragraph renders undefined statement expressions such as i = ++i + 1; a[i++] = i;` – Lundin Nov 30 '15 at 12:54
  • @Lundin Got it . Thanks for clearing that up !! :-) – ameyCU Nov 30 '15 at 12:55
1

Need to use a loop to update the 'y' value

// for loop execution
for( int i = 0; i <= 2; i++ )
{
    y[i] = i;
}
printf("y0: %d\n", y[0] );
printf("y1: %d\n", y[1] );
printf("y2: %d\n", y[2] );
jitendrapurohit
  • 9,435
  • 2
  • 28
  • 39