Ali M
Ali M

Reputation: 47

Dereferencing through pointer and incrementing gives a different value and decrements it instead C++

I was trying to do some experiments with pointers in C++, I did understand the concepts of precedence a bit but the following program is mingling with my mind and am unable to comprehend it

CODE:

#include <iostream>
using namespace std;

int main() {

    int x = 9;  
    int* ptr = &x;

cout << "The value of x is " << x << endl << "The value of ptr is " << ptr << endl << *ptr << endl << (*ptr)++ << endl << (*ptr)++ << endl << (*ptr)++ << endl;

    return 0;
}

in this program gave the initial value to x as 9 and i expect the compiler to give me value of x as 9 and then increment it using pointers so i expected the answer to be as 9,Address,9 ,10,11,12 but instead the answer i get in every compiler is that the value of x is 12 and rest is like this 12,Address,11,10,9 Please help me understand this am a newbie in C++

Upvotes: 1

Views: 203

Answers (3)

john
john

Reputation: 87959

This has nothing to do with precedence but with order of evaluation. You are assuming that the order of evaluation is left to right, but this is not true. As you can see, in your case, it's right to left.

However this is an area where C++ has changed. With the C++17 version the rules for expressions such as the above where changed to guarantee left to right order of evaluation. So if you can, use the compiler options that forces version C++17 and you should see the result change.

Left to right order of evaluation is not guaranteed everywhere, for instance given A + B, it still could be A before B or B before A. Full details can be found here.

Upvotes: 4

Arty
Arty

Reputation: 16747

Use ++(*ptr) instead of (*ptr)++ to achieve result that you want.

++x increments value of x and then returns new incremented value, while x++ increments x but returns previous value (copy) of x.

And according to your expectations to have 9, Address, 9, 10, 11, 12 you really wanted to have behavior of ++x hence using of ++(*ptr) is needed.

You can see corrected code in action here online.

Update.

In fact it appeared to be that same code even with pre-increment ++(*ptr) behaves differently on different compilers, my MSVC 2015 and 2019 outputs 12 addr 12 12 12 12 and if I use /std:c++latest flag in MSVC then output is correct expected 9 addr 9 10 11 12, so behavior changed in C++11 or later.

So it means that behavior of such expressions is UNDEFINED meaning that it is different and maybe even random on different compilers.

So you need to definitely avoid such expressions if you want compatibility in all versions of compilers. Or use /std:c++latest for MSVC and similar flags for other compilers, to force using latest C++ standard.

To avoid problems you may store incremented results into separate variables or array and then output it to cout.

Upvotes: 0

guapi
guapi

Reputation: 123

This is an undefined behavior.

For more detailed information, you can go to this post: What made i = i++ + 1; legal in C++17?

Upvotes: 0

Related Questions