This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 3 years ago.
I was reading this question about sequence points and I saw this line:
i = (i, ++i, 1) + 1; // well defined (AFAIK)
I was wondering how is the following syntax called and what are its effects?
i = (a1, a2, ...,an);
This is the comma operator for int operands, together with grouping through parentheses, which is always allowed. First,
(i, ++i, 1)
evaluates i, then ++i, then 1 and returns the result of the last expression (which is 1). Then
(i, ++i, 1) + 1
is the same as
1 + 1;
which results in 2, so i is set to 2 here. Note that without the parentheses, the result would in most cases not be the same, as the comma operator has the lowest possible precedence (thanks to #dbush for helping me out here in the comments).
Related
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.
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.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
What is the way of working out:
int i=5;
a= ++i + ++i + ++i;
If we go by normal right to left evaluation, the result should be 21 (6 + 7 + 8) .
I remember studying in school, that the answer was 24(8 + 8 + 8)
But I tried it on CodeBlocks, www.ideone.com, ie gcc 4.8.1 compiler and now I get 22.
Could someone please explain the reason
There are no Sequence Points in that expression, so you can't work it out, it is undefined/compiler dependant.
It is as defined by the C/C++ standards an undefined or implementation-defined behavior. The language standards do not specify the behavior, it allows the compiler implementation to choose (and is usually documented).
Also look at another StackOverflow question: Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…).
What GCC does in your example is the following:
int i = 5;
a = ++i + (++i + ++i); // it first gets the value of i and increments it two times
a = ++i + (7 + 7); // it then reads the new value of i, does the addition and save it as a constant in the stack
a = ++i + 14; // it then gets the value of i and increments it
a = 8 + 14; // it then reads the new value of i and add it to the constant
a = 22;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Comma Operator
Uses of C comma operator
I am not new to C++, but this is the first time I see the following code:
int a=0;
int b=(a=2,a+1);
That is C++ code. Can you tell me what is going on here? And how variable b gets value 3?
This code is equivalent to this:
int a = 2 ;
int b = a + 1 ;
First expression to the left of comma gets evaluated, then the one to its right. The result of the right most expression is stored in the variable to the left of = sign.
Look up the comma operator for more details.
http://en.wikipedia.org/wiki/Comma_operator
(a = 2, a + 1); return 3 because in general case operator (a, b) return b, and calculation in (a, b) started from right to left. So, in your case, (a = 2, a + 1) return a + 1, and after operator a = 2 was executed a + 1 return 3.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
Why this code is generating 8 as a result ?
#include <iostream>
using namespace std ;
void myFunction(int i)
{
i = i + 2 + ++i;
cout<<i<<endl;
}
void main ()
{
int i = 2;
myFunction(i);
cin>> i;
}
I think the result should be 7 not 8...I am using Visual Studio 2008
The order of evaluation of terms on the right hand side of this expression
i = i + 2 + ++i;
is undefined. i.e. they can occur in any order. In this case the compiler has chosen to increment i first (++i, third term), before evaluating i (first term), which results in 3 + 2 + 3.
You are changing i twice in one statement, and also referencing its value in a way not connected to changing it. This is undefined behavior, and there is no single right answer.
Unspecified behavior. It could be any value. You're not allowed to modify a variable more than once in a single sequence point.
The ++i is executed before all other statements are, so in the line i + 2 + ++i the result is (with i=2) 3 + 2 + 3 which is 8.
It's evaluating "++i" first. "i" is then 3 so you end up with 3 + 2 + 3 = 8.
This is an excellent example of why you should be careful with operators!