Reputation: 156
Confused about the output for the second code snippet. Why is the output different than the first program?
#include <iostream>
using namespace std;
int main() {
int s[5] = {1, 2 , 3, 4, 5};
int *p = s;
int first = *(p++);
int second = *++p;
int third = ++*p;
int fourth = *p++;
cout << "*p++ is " << first << endl
<< "*++p is " << second << endl
<< "++*p is " << third << endl
<< "*p++ is " << fourth << endl;
return 0;
}
*p++ is 1
*++p is 3
++*p is 4
*p++ is 4
I expected the output would be the same in the code below:
#include <iostream>
using namespace std;
int main() {
int s[5] = {1, 2 , 3, 4, 5};
int *p = s;
cout << "*p++ is " << *p++ << endl
<< "*++p is " << *++p << endl
<< "++*p is " << ++*p << endl
<< "*p++ is " << *p++ << endl;
return 0;
}
*p++ is 3
*++p is 3
++*p is 3
*p++ is 1
What's going on?
Upvotes: 3
Views: 182
Reputation: 156
Between consecutive "sequence points" an object's value can be modified only once by an expression.
https://msdn.microsoft.com/en-us/library/azk8zbxd.aspx
The second code snippet attempts to modify the pointer's value multiple times within one sequence.
List of C Sequence Points:
Left operand of the logical-AND operator (&&).
Left operand of the logical-OR operator (||).
Left operand of the comma operator (,)
Function-call operator ()
First operand of the conditional operator aka ternary operator ( ? : )
The end of a full initialization expression (that is, an expression that is not part of another expression such as the end of an initialization in a declaration statement).
The expression in an expression statement. Expression statements consist of an optional expression followed by a semicolon (;). The expression is evaluated for its side effects and there is a sequence point following this evaluation.
The controlling expression in a selection (if or switch) statement.
The controlling expression of a while or do statement.
Each of the three expressions of a for statement.
The expression in a return statement.
Upvotes: 0
Reputation: 1
As per operator precedence, operator << is left to right which occurs in cout object in sequence one after the other and sequence of evaluation of arguments to operator << is unspecified.
Upvotes: 0
Reputation: 35164
Your statement cout << "*p++ is " << *p++ << endl << ...;
is treated as one expression, and C++ is almost free in the order of evaluating the arguments used in expressions. SO it is undefined (behaviour actually) in which order the p++
and ++
-statements are evaluated.
In the first approach, evaluation order is according to the variables to which you assign. In the second, C++ is free (and treats it as UB if there is no sequence point in the expression; in your's, there isn't a sequence point).
Upvotes: 5