0

This is an excercise in my textbook. I need to find the output of this code.

#include<iostream>
using namespace std;
int main()
{
    int x[]={10,20,30,40,50};
    int *p,**q,*t;
    p=x;
    t=x+1;
    q=&t;
    cout<<*p<<","<<**q<<","<<*t++;
    return 0;
}

The output is

10,30,20

Here I dont understand the declaration of **q, and also how its value comes out to be 30. I also noticed that changing the last statement to

cout<<*p<<","<<**q<<","<<*t;

changes the output to

10,20,20 

Could somebody explain what goes on behind the scenes here? Thanks a lot in advance.

Sharat
  • 147
  • 7
  • 6
    Throw out the textbook ASAP. – interjay Sep 10 '15 at 13:35
  • 1
    Read on Sequence Points (https://en.wikipedia.org/wiki/Sequence_point) and http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Abhineet Sep 10 '15 at 13:37
  • 1
    @Abhineet I think that topic is too advanced for a beginner, author of this crappy book needs to read it. +1 to interjay - throw out this. – Slava Sep 10 '15 at 13:39
  • 2
    To clarify, the behavior of the code is undefined because the modification and access to `t` are unsequenced with regard to each other. Additionally, `main` must return `int` and not `void`. Unless the book was specifically teaching what undefined behavior is and how to avoid it, this is a terrible exercise. – interjay Sep 10 '15 at 13:43
  • School textbook... I can't throw it out. I corrected the return int part. – Sharat Sep 10 '15 at 13:49
  • 1
    @SharatSachin, [this tutorial](http://www.tutorialspoint.com/cplusplus/cpp_pointer_to_pointer.htm) will help you understand the declaration of `**q` – Pooja Nilangekar Sep 10 '15 at 13:51

3 Answers3

2

Here, q is a pointer to a pointer to int, and it was set to point to t. So *q is identical to t, and **q is *t. Which means the cout expression can be rewritten as:

cout<<*p<<","<<*t<<","<<*t++;

Here you can see that t is read and modified in different parts of the expression, and the standard says that the order in which these parts are executed is not specified. So t may be modified before or after (or even while) it is read. When this kind of thing (unsequenced read and write to a variable) happens, we get undefined behavior: Anything can happen as a result. A specific compiler may give a specific result on a specific computer, but there is no guarantee that you will always get this result.

So this exercise is invalid, and there is no point in trying to figure out why you saw a specific output.

On the other hand, the second line you attempted:

cout<<*p<<","<<**q<<","<<*t;

is perfectly valid, because it doesn't modify t anywhere.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • Is the behaviour really undefined or is the result merely unspecified? – eerorika Sep 10 '15 at 14:28
  • 1
    @user2079303 It's undefined. From the standard: "If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent (1.10), the behavior is undefined". – interjay Sep 10 '15 at 14:38
0

p and t are both of the type pointer to int, q is of the type pointer to (pointer to int)

The * operator makes a pointer to a reference.

So *p is of the type int&, so is *t. *q is of the type int*& (read reference to a pointer to int)

You want to print an int value here and must therefore use the * operator a second time.

So the **q is just making a pointer to a pointer to int to a reference to int


I forgot to mention it: The process is called dereferencing pointers.

Maybe the descirption on this side will give you a better insight: http://www.cplusplus.com/doc/tutorial/pointers/

Simon Kraemer
  • 5,700
  • 1
  • 19
  • 49
-2

++ operator has higher precedence than << When program is executed this are events:

int x[]={10,20,30,40,50};
int *p,**q,*t; 
p=x;
t=x+1;
q=&t;
cout<<*p<<","<<**q<<","<<*t++; //1st change value of t to t+1, 
//but return old t in place ^
//then to output stream 'p'=10, then 'q'=new 't'=old 't'+1=30, 
//then old 't'=20 which is returned by sufix ++ operator 
Kamil
  • 170
  • 3
  • 9
  • There is no guarantee that the `t++` will happen before reading the value of `**q`. So the behavior is undefined. – interjay Sep 10 '15 at 13:48
  • There is no point to describe order of event for undefined behavior. It just happened this time this way. – Slava Sep 10 '15 at 13:56