I have been fooling around with some code and saw something that I don't understand the "why" of.
int i = 6; int j; int *ptr = &i; int *ptr1 = &j j = i++; //now j == 6 and i == 7. Straightforward.
What if you put the operator on the left side of the equals sign?
++ptr = ptr1;
is equivalent to
(ptr = ptr + 1) = ptr1;
whereas
ptr++ = ptr1;
is equivalent to
ptr = ptr + 1 = ptr1;
The postfix runs a compilation error and I get it. You've got a constant "ptr + 1" on the left side of an assignment operator. Fair enough.
The prefix one compiles and WORKS in C++. Yes, I understand it's messy and you're dealing with unallocated memory, but it works and compiles. In C this does not compile, returning the same error as the postfix "lvalue required as left operand of assignment". This happens no matter how it's written, expanded out with two "=" operators or with the "++ptr" syntax.
What is the difference between how C handles such an assignment and how C++ handles it?
= operator is used to assign value to a variable and == operator is used to compare two variable or constants. The left side of = operator can not be a constant, while for == operator both sides can be operator.
In a nutshell, the main difference between C and C++ is that C is a procedural with no support for objects and classes whereas C++ is a combination of procedural and object-oriented programming languages.
C++ is a superset of C, so both languages have similar syntax, code structure, and compilation. Almost all of C's keywords and operators are used in C++ and do the same thing. C and C++ both use the top-down execution flow and allow procedural and functional programming.
In both C and C++, the result of x++
is an rvalue, so you can't assign to it.
In C, ++x
is equivalent to x += 1
(C standard §6.5.3.1/p2; all C standard cites are to WG14 N1570). In C++, ++x
is equivalent to x += 1
if x
is not a bool
(C++ standard §5.3.2 [expr.pre.incr]/p1; all C++ standard cites are to WG21 N3936).
In C, the result of an assignment expression is an rvalue (C standard §6.5.16/p3):
An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
Because it's not an lvalue, you can't assign to it: (C standard §6.5.16/p2 - note that this is a constraint)
An assignment operator shall have a modifiable lvalue as its left operand.
In C++, the result of an assignment expression is an lvalue (C++ standard §5.17 [expr.ass]/p1):
The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.
So ++ptr = ptr1;
is a diagnosable constraint violation in C, but does not violate any diagnosable rule in C++.
However, pre-C++11, ++ptr = ptr1;
has undefined behavior, as it modifies ptr
twice between two adjacent sequence points.
In C++11, the behavior of ++ptr = ptr1
becomes well defined. It's clearer if we rewrite it as
(ptr += 1) = ptr1;
Since C++11, the C++ standard provides that (§5.17 [expr.ass]/p1)
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.
So the assignment performed by the =
is sequenced after the value computation of ptr += 1
and ptr1
. The assignment performed by the +=
is sequenced before the value computation of ptr += 1
, and all value computations required by the +=
are necessarily sequenced before that assignment. Thus, the sequencing here is well-defined and there is no undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With