Elfen Dew
Elfen Dew

Reputation: 156

Operator precedence with cout and pointers

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;
}

output:

*p++ is 1
*++p is 3
++*p is 4
*p++ is 4

https://ideone.com/Qu2uIJ

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;
}

output:

*p++ is 3
*++p is 3
++*p is 3
*p++ is 1

https://ideone.com/nwd7xR

What's going on?

Upvotes: 3

Views: 182

Answers (3)

Elfen Dew
Elfen Dew

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

Chetan Rangappa
Chetan Rangappa

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

Stephan Lechner
Stephan Lechner

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

Related Questions