Reputation: 41
If I run the following code, graph[0][0]
gets 1
while graph[0][1]
gets 4
.
In other words, the line graph[0][++graph[0][0]] = 4;
puts 1
into graph[0][0]
and 4
into graph[0][1]
.
I would really appreciate if anyone can offer reasonable explanation.
I observed this from Visual C++ 2015 as well as an Android C compiler (CppDriod).
static int graph[10][10];
void main(void)
{
graph[0][++graph[0][0]] = 4;
}
Upvotes: 2
Views: 114
Reputation: 320461
Let's line up the facts about this expression
graph[0][++graph[0][0]] = 4;
Per 6.5.1, the computation of the array index ++graph[0][0]
is sequenced before the computation of array element graph[0][++graph[0][0]]
, which in turn is sequenced before the computation of the entire assignment operator.
The value of ++graph[0][0]
is required to be 1
. Note that this does not mean that the whole pre-increment together with its side-effects has to "happen first". It simply means that the result of that pre-increment (which is 1
) has to be computed first. The actual modification of graph[0][0]
(i.e. changing of graph[0][0]
from 0
to 1
) might happen much much later. Nobody knows when it will happen exactly (sometime before the end of the statement).
This means that the element being modified by the assignment operator is graph[0][1]
. This is where that 4
should go to. Assignment of 4
to graph[0][1]
is also a side-effect of =
operator, which will happen sometime before the end of the statement.
Note, that in this case we could conclusively establish that ++
modifies graph[0][0]
, while =
modifies graph[0][1]
. We have two unsequenced side-effects (which is dangerous), but they act on two different objects (which makes them safe). This is exactly what saves us from undefined behavior in this case.
However, this is dependent on the initial value of graph
array. If you try this
graph[0][0] = -1;
graph[0][++graph[0][0]] = 4;
the behavior will immediately become undefined, even though the expression itself looks the same. In this case the side-effect of ++
and the side-effect of =
are applied to the same array element graph[0][0]
. The side-effects are not sequenced with relation to each other, which means that the behavior is undefined.
Upvotes: 0
Reputation: 134326
First let's see what is the unary (prefix) increment operator does.
The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation.
So, in case of
graph[0][++graph[0][0]] = 4;
first, the value of graph[0][0]
is incremented by 1, and then the value is used in indexing.
Now, graph
being a static global variable, due to implicit initialization, all the members in the array are initialized to 0
by default. So, ++graph[0][0]
increments the value of graph[0][0]
to 1 and returns the value of 1
.
Then, the simpllified version of the instrucion looks like
graph[0][1] = 4;
Thus, you get
graph[0][0]
as 1graph[0][1]
as 4.Also, FWIW, the recommended signature of main()
is int main(void)
.
Upvotes: 2
Reputation: 116
At first your variable graph[10][10]
is static so it will be initialized with value 0
.
Then line graph[0][++graph[0][0]] = 4 ;
here graph[0][0] = 0 in expression you just incrementing the value of graph[0][0] so basically you assigning graph[0][1] = 4;
yourself
Note that you have used pre-increment operator (++x) so it first get incremented and value is changed but if you would have use post-increment operator(x++) then graph[0][0] = 4;
itself
Upvotes: 1
Reputation: 41
You are adding one to graph[0][0]
, by doing ++graph[0][0]
. And then setting graph[0][1]
to 4
. Maybe you want to do graph[0][graph[0][0]+1] = 4
Upvotes: 1
Reputation: 9270
Let's break it down:
++graph[0][0]
This pre-increments the value at graph[0][0]
, which means that now graph[0][0] = 1
, and then the value of the expression is 1
(because that is the final value of graph[0][0]
).
Then,
graph[0][/*previous expression = 1*/] = 4;
So basically, graph[0][1] = 4;
That's it! Now graph[0][0] = 1
and graph[0][1] = 4
.
Upvotes: 5