-2
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{

     int y,**p,*pt;
     int x=5;
     pt=&x;
     p=&pt;
     y=**p + ++(**p);
     cout<<*pt<<" "<<**p<<" "<<x<<" "<<y;
     getch();
     return(0);
}

output generated 6 6 6 11, why not 6 6 6 12 kindly guide on execution step. Here my doubt is **p is pointing to x only which is incremented by second operand ++(**p). so value of y should be 12.

  • `y=**p + ++(**p);` makes 11. There is no ambiguity here with the brackets. What was 5, x, becomes 6, left of that the old value had already been read, as 5. 5+6=11 – John Sep 14 '19 at 09:57
  • 1
    @John You seem to assume that left side of `+` is guaranteed to be evaluated first. – user7860670 Sep 14 '19 at 10:00
  • There is an extra section [Undefined Behavior](https://en.cppreference.com/w/cpp/language/eval_order#Undefined_behavior) in [Order of evaluation](https://en.cppreference.com/w/cpp/language/eval_order) on cppreference.com listing among others your example: `n = ++i + i; // undefined behavior`. That `i` is `**p` in your case doesn't change anything (IMHO). – Scheff's Cat Sep 14 '19 at 10:54
  • This is one reason not to embed assignations within expressions. If the value of a term has to change within the expression, then split the expression and make the needed change in-between. Ppl tend to wrongly assume that dense source code produces dense or efficient execution. This is so most often wrong premature optimization that may instead create side-effects or as here has undefined behavior. – Léa Gris Sep 14 '19 at 11:17
  • Another nice Q/A about this: [SO: Absurd output. Gives different output with and w/o debugging. Need expert intervention](https://stackoverflow.com/q/47620930/7478597) – Scheff's Cat Sep 14 '19 at 11:18
  • here my doubt is: p is pointing to x. so whichever expression of (+) executes first how it is really matter. is it that if **p expression evaluates first then its value is stored in some register or stack?? – user1543087 Sep 16 '19 at 08:51

1 Answers1

1

This is classic undefined behaviour! There is no guarantee in the C++ standard about the order of evaluation of the operands of the + operator in y=**p + ++(**p).

I tested your code in MSVC and clang-cl and I get the output: 6 6 6 12 - which suggests (as you expect) that ++(**p) is evaluated first. However, on your compiler, it seems that the LHS is evaluated first.

From the cppreference site linked in the comments by Scheff:

Order of evaluation of any part of any expression, including order of evaluation of function arguments is unspecified (with some exceptions listed below). The compiler can evaluate operands and other subexpressions in any order, and may choose another order when the same expression is evaluated again. There is no concept of left-to-right or right-to-left evaluation in C++….

PS: Interestingly, changing to y = ++(**p) + **p; also gives 6 6 6 12 as the output.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • @Scheff - I sort of agree. The point is, two different compilers give two different answers, so it ***is*** undefined behaviour! – Adrian Mole Sep 14 '19 at 11:01
  • That's not general enough. The _same_ compiler is free to give two different answers in the same binary and without any obvious reason. That's why _undefined_ behavior. What you suggest is rather implementation defined behavior but that it's not. – Scheff's Cat Sep 14 '19 at 11:02
  • 1
    Once, you recompiled a program with a new version of compiler and out of a sudden it crashs immediately (ignoring the fact that it's successfully sold and used by customers for years before) - you start to fear Undefined Behavior as I do. ;-) (And such experiences move theoretical concerns into the daily business - very practically.) – Scheff's Cat Sep 14 '19 at 11:05
  • About the different compilers: https://wandbox.org/permlink/Yxh3J1LSKOcl69sq , but note how kind gcc can be: https://wandbox.org/permlink/dJSAJpFw9EclV5SE – Bob__ Sep 16 '19 at 09:51