What exactly does the "+=" operator do? [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I already know that x += 1 means x = x + 1.
The =-symbol allocates the value of the arithmetic expression on it's right to the variable on it's left.
But if i have an expression like x += y % 3, does that mean x = (x + y) % 3or x = x + (y % 3)?
The += operator is both allocating a value to a variable and expressing arithmatics, which has me confused.
Unfortunately I currently can't just test some code to check, so I hope I can get some help here.
I'm new to C++, so some of these very basic things still confuse me...

The =-symbol allocates the value of the arithmetic expression on it's right to the variable on it's left
It assigns the result. Allocation is something different, and it'll be important to remember the difference later (dynamic allocation in particular will be really confusing if you conflate it with assignment).
But if i have an expression like x += y % 3, does that mean x = (x + y) % 3 or x = x + (y % 3)?
Part of the reason for having the compound +=, -= etc. operators is that you don't expand the expression like this, avoiding the ambiguity created by your re-write.
x += y % 3
can be read as
tmp = y % 3; // evaluate right hand side
x += tmp; // assign to left hand side
(you can expand x += tmp to x = x + tmp if you really want to, after tmp has been evaluated).
The rules are all documented here in any case, and anyway you absolutely can just test some code to check: https://ideone.com/81tvjH

There is a confusion here, because you think x += 1; is always x = x + 1. This is true for integers, doubles... but generally NOT the case for other objects. Lots of implementations don't create a temporary object. Or could do something very evil.
So then it's a call to operator+=, which takes as the argument the result of the right hand side of the assignment.
So for integers, it's x = x + (y % 3).

Related

I want to pre-increment an assignment to a variable (pre-increment by value more than 1)? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to pre-increment a value assignment in a for loop
for (int x=0; x<100; x+=increase){
// loop operation here
}
The code above post increments the value, however I want to pre increment it. I know I can pre-increment by one with the ++i syntax, however is there a way to pre increment through variable assignment.
It sounds like you have two misconceptions.
x += y is already "equivalent" to preincrement, in that x += 1 is, by definition, identical to ++x. (The point is that the value of x += y is the updated value of x, just as the value of ++x is the updated value.) It's the postincrement form x++ that has no exact equivalent for adding increments other than 1.
When you write for(x = 0; x < 100; x += increase), you're not immediately using the value of the expression x += increase, so it doesn't matter if you use a preincrement or postincrement form.
If you want your loop to start with an initial value of increase rather than 0, just write
for(x = increase; x < 100; x += increase)

C++ Boolean with Integers

OK so obviously this question might sound dumb for more experienced people, but, for the following lines the result I get is 0:
int x = 2,
y = -2;
cout << (x++ - y && (--x + y));
I understand it means that either one of these two expressions equals 0, but how? As far as I understand, this should be (3 && -1)?
Also, a little subquestion: when does x++ exactly take effect? On the next occurance of x within the same expression, after the left-shift operator within the same line, or in the next statement?
Thank you!
As far as I understand, this should be (3 && -1)?
you understand wrong:
first left side is fully evaluated, as it is necessary for short circuit evaluation with logical and (details can be found here)
x++ - y == 4 // as result of x++ == 2 so (2-(-2)), after that x == 3
result is true so right side is evaluated:
--x + y == 0 // as result of --x == 2 so (2+(-2)), after that x == 2
result on the right is false so result of and is false as well which printed by std::ostream as 0
Note: short circuit evaluation of logical or and and operations make such code valid (making them sequenced) but you better avoid such questionable expressions. For example simple replacing logical and to binary would make it UB.

What can be a subexpression?

I read "C++.Primer plus. Stephen Prata"(6th edition).
On page 209 was:
y = (4 + x++) + (6 + x++);
The expression 4 + x++ is not a full
expression, so C++ does not guarantee that x will be incremented
immediately after the subexpression 4 + x++ is evaluated. Here the
full expression is the entire assignment statement, and the semicolon
marks the sequence point, so all that C++ guarantees is that x will
have been incremented twice by the time the program moves to the
following statement. C++ does not specify whether x is incremented
after each subexpression is evaluated or only after all the
expressions have been evaluated, which is why you should avoid
statements of this kind.
And I read "Sequence Points and Expression Evaluation" Visual Systems Journal, August 2002. Klaus Kreft & Angelika Langer.
There was:
x[i]=i++ + 1;
Let's assume variable i has the value 1 before we enter the statement.
What will be the result of evaluation of this expression? The correct
answer is: we don't know. However, programmers ever too often believe
that they know what this program fragment does. Typical answers
include: "x[1] will have the value 2", or "x[2] will have the value
2", or even "x[1] will have the value 3".
The third option is definitely wrong. This will not happen because i++
is a postfix increment and returns i's initial value 1; hence the
value of the right hand side of the assignment is 2, and definitely
not 3. [...] So far so good, but we do not know
which entry of the array x will be modified. Will the index be 1 or 2
when the right hand side value will be assigned to x[i]?
There is no definite answer to this question. It fully depends on the
order in which the compiler evaluates the subexpressions. If the
compiler starts on the right hand side of the assignment and evaluates
i++ + 1 before it figures out which position in the array x must be
assigned to then x[2] will be modified because i will have already
been incremented in the course of evaluating the subexpression i++.
Conversely, if the compiler starts on the left hand side and figures
out that it must assign to position i in array x, which at that time
will still be position 1, before it evaluates the right hand side then
we'll end up with a modification of x[1]. Both outcomes are equally
likely and equally correct. "
How understand where is subexpression?
4 + x++ and 6 + x++ are subexpressions, because they are into round brackets?
x[i] and i++ + 1 are subexpression? Why?
I'm interested in this, because I want to understand where side effect can happened in the hypothesis.
Breaking this down, the line
y = (4 + x++) + (6 + x++);
is an expression-statement. Such a thing consists of an expression followed by a ;, so
y = (4 + x++) + (6 + x++)
is an expression.
Since this expression is not part of another expression (but only of an expression-statement), it is a full-expression. A sub-expression on the other hand is an expression that is part of another expression. In the following, I will use capital letters to name expressions, rather than C++ identifiers.
The full-expression above is an assignment-expression of the form:
y = A
where A is the remaining additive-expression
(4 + x++) + (6 + x++)
An additive expression is of the form X + Y, so we break this down into two expressions
(4 + x++)
(6 + x++)
The first one consists of an expression of the form (Z), where Z is 4 + x++. And 4 + x++ consists of two expressions 4 and x++. And so on. All of these expressions are part of
y = (4 + x++) + (6 + x++)
and hence they are sub-expressions of the above expression.
What can be a subexpression?
Any expression can be a subexpression. Although, some expressions may not be subexpressions of certain other expressions.
4 + x++ and 6 + x++ are subexpressions
Correct. Both of those are arithmetic expressions, additions to be more specific.
because they are into round brackets?
Well, sort of. Being inside parentheses, they are indeed the subexpression of the parenthesized expression.
† In general, they're subexpressions because they're expressions, but are also part of another expression.
x[i] and i++ + 1 are subexpression? Why?
Yes, they are. See †.
Here is a handy list of all possible expressions in c++.
Let's find the subexpressions in y = (4 + x++) + (6 + x++);. The first expression that has no subexpressions is 4. It is a literal. It is a subexpression of 4 + x++ which is an addition. Additions have the form A + B. In this case, subexpression A is 4 an subexpressiond B is x++, which is a post increment. Oh, but that contains a subexpression too: x. It is an identifier, and contains no subexpressions. 4 + x++ is a subexpression of the parenthesized expression (4 + x++). That is a subexpression of (4 + x++) + (6 + x++) which is a subexpression of y = (4 + x++) + (6 + x++); which is an assignment. The assignement is a full-expression - not a subexpression. I left some of the subexpressions unexplored, and I shall leave them as an exercise for the reader.

Magic in C++ with this expression x = y - x + (y = x) [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
In Python, you can easily exchange the values of 2 variables with an expression like this:
x, y = y, x
In C++, on the other hand, if you want to exchange the values of 2 variables, you usually use a temporary variable to store the value of one of your variables, something like this:
int var1 = 100;
int var2 = 200;
int temp = var1;
var1 = var2;
var2 = temp;
This is easy, but you have to write a lot of code.
A professor that I have been following for his lectures on C++ has discovered a new compact way of exchange the values of 2 variables in a magic way:
int x = 200;
int y = 100;
x = y - x + (y = x);
It seems incredible, but it works both with the compiler he's using and mine Apple LLVM version 6.0 (clang-600.0.56).
It seems that the way that expression is interpreted is the following:
(y = x) // returns the value of x
-x + x = 0
x = y + 0
x = y
y = x // finally, y receives the initial value of x
If I try to exchange the values of some variables in a loop, it seems also to work:
for (int i = -10; i <= 10; i++) {
for (int j = 10; j >= -10; j--) {
int x = i, y = j;
x = y - x + (y = x);
std::cout << "x = " << x << "\ny = " << y << '\n';
}
}
We have seen that the exchange is done, but my compiler gives me this warning:
main.cpp:28:22: warning: unsequenced modification and access to 'y'
[-Wunsequenced]
If there's a warning, I suppose this is not a new standard way of exchanging the values of 2 variables, but was just an ingenious workaround of this professor.
Why this method is not standardised in C++, and why exactly does it work?
This is undefined behavior, and it's not guaranteed to work. The order of evaluation of the parameters in an expression is not specified. So it's allowed to access the value of y for the subtraction before or after it performs the y = x assignment.
The reason it's specified like this is to allow flexibility for optimizations.
It "works" because you were unlucky.
Yes, I said unlucky. The code has undefined behavior; the fact that it appears to "work" means that your compiler has let you get away with code that could fail next time you run it.
x = y - x + (y = x);
The object y is accessed twice, once to read its value and once to assign a value to it. The language does not define the order in which those accesses occur -- or that the occur in any order at all. As the warning message says, they're "unsequenced". The possible behaviors are not limited to the two possible orders; the behavior is entirely undefined.
Furthermore, the addition and/or subtraction could overflow, which is another potential source of undefined behavior.
This, `x = y - x + (y = x);, is undefined behavior in C - one undefined behavior listed by the C99 spec is:
Between two sequence points, an object is modified more than once, or
is modified and the prior value is read other than to determine the
value to be stored
The only sequence points in this expression are the beginning of the expression and the end of the complete expression.

Any idea why the code snippet below prints 2 and not 3 [duplicate]

This question already has answers here:
Post increment and Pre increment in C
(3 answers)
Closed 9 years ago.
I was expecting this code snippet to print 3 as the if condition is false and y++ will execute, but it prints 2, any idea why..Thanks!!
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x++ : y++);
// This prints 2
x++ and y++ are post-increment. That is, they return the current value of the variable, then add one to it.
Pre-increment would be ++x or ++y. Those increment and then return the new value.
Both pre- and post-increment (and -decrement) are useful things when writing loop controls, which is why C supports both.
(Originally, if I remember correctly, C only supported pre-increment and post-decrement, because there happened to be instructions on the machines it was developed on which encapsulated those behaviors. But as C moved to other systems, and as people started noticing that they wanted both pre and post for both, this was generalized.)
Note that this means the c++ language was misnamed. It should have been called ++c -- we want it improved before we use it, not after!
It's because y++ returns the value of y then increases it.
Where as if you put ++y it would increase the value of y first then return it.
The ++ operators are evaluated last; this is called "post-increment." So, this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x++ : y++);
is equivalent to this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? x : y);
y++;
(x++ isn't ever reached because of the ternary condition.) On the other hand, this:
int x = 3;
int y = 2;
printf("%d\n", (x<y) ? ++x : ++y);
would increment y before returning its respective value to printf(), so the logic would be:
printf("%d\n", (3<2) ? 3 : 3); // prints 3
Since you use a post increment y++, value of y will be used first and incremented. That is the printf will be passed the value before increment operation, in your case y is 2 before increment and 2 will be printed.
You should consider x++ and y++ after all the other operations of this line have been completed. So, print y and then increment x and y.