I'm confused about the behavior of the post-decrement (i--) and pre-decrement (--i) operators in C, especially when used in the context of array indexing and assignment. I'm trying to understand the execution order between the decrement and the assignment operation.
Here is my code:
#include <stdio.h>
int main() {
int arr1[] = {11, 12, 13, 14, 15, 16};
int arr2[] = {21, 22, 23, 24, 25, 26};
int i = 5;
arr1[i--] = arr2[i]; //1st assignment
int arr3[] = {11, 12, 13, 14, 15, 16};
int arr4[] = {21, 22, 23, 24, 25, 26};
int j = 5;
arr3[j] = arr4[j--]; //2nd assignment
return 0;
}
For the first assignment (arr1[i--] = arr2[i];
):
Since i
is initially 5, I expected arr1[5] = arr2[4]
, which should make arr1[5] = 25
.
So, arr1
should be {11, 12, 13, 14, 15, 25}
.
For the second assignment (arr3[j] = arr4[j--];
):
Since j
is also 5, I expected arr3[5] = arr4[5]
, which is arr3[5] = 26
, and then j
becomes 4.
So, arr3
should be {11, 12, 13, 14, 15, 26}
.
The first assignment behaved as expected: arr1 = {11, 12, 13, 14, 15, 25}
But the second assignment resulted in: arr3 = {11, 12, 13, 14, 26, 16}
Why does the second assignment (arr3[j] = arr4[j--];
) result in modifying arr3[4]
instead of arr3[5]
? I thought the post-decrement should use the current value before decrementing, so both indices should be 5 in this case. Could this be due to sequence point rules or undefined behavior?
Both invoke undefined behaviour (UB) as i
and j
have undefined value because of the sequence point1 problems.
What I expected:
As it is Undefined Behaviour you should have not been expecting anything.
Always enable all warnings and in most cases the compiler will warn you:
<source>: In function 'main':
<source>:6:11: warning: operation on 'i' may be undefined [-Wsequence-point]
6 | arr1[i--] = arr2[i]; //1st assignment
| ~^~
<source>:13:21: warning: operation on 'j' may be undefined [-Wsequence-point]
13 | arr3[j] = arr4[j--]; //2nd assignment
| ~^~
You need split it into two statements:
arr1[i] = arr2[i];
i--;
arr3[j] = arr4[j];
j--;
1. [There’s no sequence point (no guaranteed evaluation order) between the LHS and RHS, nor between those two uses of i
/j
. So the read and the modification are unsequenced relative to each other → UB]