0

Is that about stack? I think the last *p++ is undefined. *p++ means *(p++) or *p;p++;?

void test123()
{

    char s[] = "123", * p;
    p = s;
    // 1 2 3
    cout << *p++ << endl;
    cout << *p++ << endl;
    cout << *p++ << endl;

}
void test321()
{
    char s[] = "123", * p;
    p = s;
    //321
    cout << *p++ << *p++ << *p++ << endl;

}
int main(void)
{
    cout << "123:" << endl;
    test123();
    cout << "123:" << endl;
    test321();
    cout << "hello world" << endl;
    return 0;
}

I think the result is undefined.

Hanjoung Lee
  • 2,123
  • 1
  • 12
  • 20
  • _i think the result is undefined..._ Why do you think so? – B001ᛦ May 28 '19 at 09:18
  • but the result is not undefined !!! The reason i think result is undefined is p will be pointed unused memory affter using the last *p++ – user9981474 May 28 '19 at 09:40
  • 2
    Possible duplicate of [Order of evaluation of arguments using std::cout](https://stackoverflow.com/questions/7718508/order-of-evaluation-of-arguments-using-stdcout). Prior to c++17 evaluation order is undefined. Since c++17 it should be left to right. – dewaffled May 28 '19 at 09:48
  • if that is right,the result should be 231 when test123() return.,not 123 – user9981474 May 29 '19 at 01:19

2 Answers2

3

*p++ is evaluated to *(p++) according to operator precedence. And what p++ does is that increments p by 1 and returns the value before the increment.

From https://en.cppreference.com/w/cpp/language/operator_incdec

Post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.

Even at the last line you mentioned, p++ returns the position s+2 so dereferencing it we get 3, not the next address to it.

Except the order of evaluation(in test321), there is no undefined behavior in this code.

% If the expression was *++p it would do exactly what you said(However it is still not undefined since every string literal ends with zero(\0).

Hanjoung Lee
  • 2,123
  • 1
  • 12
  • 20
0

*p++ means *(p++) and *p;p++, because they are the same.

First ++ has a higher precedence over *, so it's computed first. Then dereferencement happens. In both cases. The thing is that p++ returns the value before the increment, as explained in the C++ standard.

Finally, as it was said int he comments, in C++17, the evaluation order was improved so that test321 behavior is well-defined. In C++11 it is indeed not.

The fact that p points to \0 is also well defined in C++17 (it would also point to the same value in C++11 because you have 4 characters, not just 3). Even with an additional ++, it would still be well-defined, unless you dereference the value. But just pointing to the end of an array is well defined as well and is why vectors can work.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62