1

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++

Arty
  • 14,883
  • 6
  • 36
  • 69
Ali M
  • 47
  • 3
  • 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 but returns previous value. And according to your question you wanted to have behavior of `++x`. – Arty Oct 31 '20 at 07:07

3 Answers3

4

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.

john
  • 85,011
  • 4
  • 57
  • 81
0

This is an undefined behavior.

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

guapi
  • 123
  • 7
0

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.

Arty
  • 14,883
  • 6
  • 36
  • 69
  • But why does it gives 12 at start when i print x ? it should give 9 at start at least as no mingling with pointers is done at that stage? – Ali M Oct 31 '20 at 09:25
  • and i ran your code on Visual Studio and DevC++ it still gives the same thing as before , no change – Ali M Oct 31 '20 at 09:28
  • @AliM Probably you have some old version or very non-common variant of compiler that evaluates `<<` operator right to left, or some other order. You may click very last link in my answer and you'll see that common compiler like `Clang` outputs your expected way. I suggest for you to use recent compiler versions and one of common compilers like `MS Visual Studio` or `GCC` or `CLang`. – Arty Oct 31 '20 at 09:29
  • @AliM What kind of visual studio you use? What version? I may check versions `2015` and `2019` that I have on my PC. – Arty Oct 31 '20 at 09:30
  • @AliM Yes, my apologize, in fact `MSVC` shows totally bad results both 2015 and 2019. So it means that this behavior for such expression is UNDEFINED meaning that it can be random for different compilers! So the only thing to do is not to use `++x` or `x++` inside `cout << ...`, you should do this increment separately and only then output resulting value to cout. You need to avoid such expressions if it is different on different compilers. – Arty Oct 31 '20 at 09:33
  • @AliM In fact on my computer MSVC 2015 and 2019 both output `12 12 12 12 12`, so such UNDEFINED-behavior expressions should be definitely avoided. – Arty Oct 31 '20 at 09:35
  • @AliM I found how to solve your issue in MSVC, just add flag `/std:c++latest` to command line of your compiler (`cl` command). There should be somewhere a way to add extra flags to compiler command line in your `Dev++` IDE. – Arty Oct 31 '20 at 09:41