Question

I've (essentially) come across the following in the wild

x = x = 5;

which apparently compiles cleanly under earlier version of gcc (generates a warning under gcc 4.5.1). As far as I can tell the warning is generated by -Wsequence-point. So my question is does this violate the wording in the standard about manipulating variables in between sequence points (i.e., it is undefined behavior per the spec) or is this a gcc false positive (i.e., it is defined behavior per the spec)? The wording on sequence points is a bit hard to follow.

I said essentially because what I actually came across (in a larger expression) was

x[0][0] = x[0][0] = 5;

but I didn't think that was material to the warning (please correct me if that is to the point and not what I've assumed is the crux of the matter).

Was it helpful?

Solution

Assuming x is of built-in type, it assigns to x twice without an intervening sequence point, which is all you need to know. The fact that both assignments are of the same value (5), and could in theory be optimized into a single assignment (if x is not volatile), is neither here nor there.

At least, that's how I interpret "modified" in the standard - assigned a value, regardless of whether it happens to be the same as the old value. Likewise, casting away const and assigning to a const object is, I think, UB regardless of whether the value you assign happens to be equal to the prior value. Otherwise there's be a huge overhead on all memory writes if an implementation wanted to put string literals into ROM, to prevent a page fault in that case, and we know by inspection that compilers don't emit that code.

A even more exciting example would be x[0][0] = x[0][i] = 5;, which assigns to the same object without an intervening sequence point if (and only if) i == 0, so is defined behaviour conditional on the value of i.

I don't see quite why a compiler might do anything unexpected in either case, but again my lack of imagination is irrelevant :-)

What ablenky says is right. If you're in some context where you can't use two statements, maybe write x[0][0] = 5, x[0][i] = 5 instead. In both your given cases, just ditch the redundant assignment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top