4

The line of code in C is

x = x |= (1 << 3);

which gives an cppCheck Error: "Expression 'x=x|=1' depends on order of evaluation of side effects"

whereas the line

x |= (1 << 3);

is ok.

I thought

x = x |= (1 << 3);

whould be the same as

x = x = x | (1 << 3);

which is just

x = (x = (x | (1 << 3)));

where actually the outer assignment to x has no effect, meaning the outcome is the same as

x |= (1 << 3);

So what exactly is CppCheck complaining about here?

edit: think it is a duplicate of why j = j++ is or is not the same as j++ which is discussed in the question referred to above.

floquet22
  • 323
  • 2
  • 15
  • 1
    You might want to read up on [sequence points](http://c-faq.com/expr/seqpoints.html). Modifying a variable twice within a single sequence point is undefined behavior. – Cornstalks Feb 15 '16 at 15:47
  • 3
    Possible duplicate of [Why are these constructs (using ++) undefined behavior?](http://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior) – too honest for this site Feb 15 '16 at 15:50

1 Answers1

4

This quote from @Cornstalks' link on sequence points explains it very well.

Expressions ... which modify the same value twice are abominations which needn't be allowed (or in any case, needn't be well-defined, i.e. we don't have to figure out a way to say what they do, and compilers don't have to support them).

The C Standard simply does not mandate anything about these types of expressions, and therefore there is no particular order of evaluation that is guaranteed in all environments.

a rather quick&&simple explanation:

x = x |= 1 is pretty much equivalent to x = x += 1 in terms of side effects(modifications to x). x = x += 1 is equivalent to x = ++x in C. This expression is a well-known undefined expression.

Read more about it [here]

Community
  • 1
  • 1
cozyconemotel
  • 1,121
  • 2
  • 10
  • 22
  • 1
    According to the C Standard "The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands.". And "3 If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.". Thus this expression is well-defined. – Vlad from Moscow Feb 15 '16 at 16:01
  • 1
    @Vlad Yes, side effects are sequenced after computations. However, the C Standard also states that "Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression." There are **two** side effects on `x` in this expression. Your second quote is quite irrelevant in my opinion. – cozyconemotel Feb 15 '16 at 19:20