Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is *p++ += 2 well defined?

I'm not sure whether statement below is well defined by standard C or not

*p1++ += 2;

or other similar statement:

*E1++ <operator>= E2

From standard C about post-increment:

The result of the postfix ++ operator is the value of the operand. After the result is obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate type is added to it.) See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.

And about coumpund-assignment:

A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once.

like image 832
dragon135 Avatar asked Oct 17 '14 02:10

dragon135


People also ask

How do you tell if a function is well-defined?

A function is well defined if it gives the same result when the representation of the input is changed without changing the value of the input. For instance, if f takes real numbers as input, and if f(0.5) does not equal f(1/2) then f is not well defined (and thus not a function).

How do you check if a map is well-defined?

Let ϕ:S/R→T be a mapping such that: ϕ([[x]]R)=f(x) Then ϕ:S/R→T is well-defined if and only if: ∀(x,y)∈R:f(x)=f(y)

How do you check if a binary operation is well-defined?

You need to show the result of the operation lands in G. In other words, you have to show x,y∈G⟹x∗y∈G.

How do you show that addition is well-defined?

Theorem. Addition is well defined modulo m, that is, if a = b mod(m) and c = d mod(m), then (a+c) = (b+d) mod(m).


2 Answers

Let's rewrite slightly to make it more clear:

(*p1++) += 2

So the old value of p1 will be dereferenced, and 2 will be added to its referent. And p1 will be incremented after it is dereferenced (or at least, after its old value is loaded and waiting to be dereferenced). There's no problem here: none of the pieces is used more than once.

That being said, you should consider rewriting the code for clarity:

*p1 += 2;
++p1;
like image 140
John Zwinck Avatar answered Oct 21 '22 14:10

John Zwinck


Postfix increment operator (++) gives the value of operand, i.e. it gives an r-value. The r-value implies that it be used on the left of the assignment operator (=) as an operand.

int i = 0;
i++ = 0   // [Error] lvalue required as left operand of assignment  

In case of

*p1++ += 2;  

postfix ++ is not applied on *p1, but it is applied to pointer p1++. This is because postfix ++ has higher precedence than that of derereference operator *. So, compiler will parse the above statement as

*(p1++) += 2;

and this says that:

  • *p1 must be evaluated (to produce a variable) before adding 2 and assigning the result to it.
  • Result to be stored to *p1 must be evaluated before the increment to p1.
  • Once *p1 is evaluated, p1 can be increment at any time.
like image 41
haccks Avatar answered Oct 21 '22 13:10

haccks