368 views

Consider the following declaration of struct.

struct myst{
char a[20];
char *b;
struct myst *p;
}x[2] = {"GATE", "Overflow", x+1, "GO", "Classes", x}, *p = x;


What will be the output of the following print statement?

printf("%s", p++->p->b++);

1. Overflow
2. Classes
3. verflow
4. lasses

### 1 comment

Everything is there in "p++->p->b++" :

printf("%s", p++->p->b++);

(p++)→ p→ (b++) : p points to x[0].

x[0] → p: means p pointer inside a struct, which is (x+1).

(x+1) → b++ : this will give Classes & b will shift to “lasses” as it is a post-increment.

So, the output is “Classes”, if (++b) is used then output will be : “lasses”.

https://en.wikipedia.org/wiki/Sequence_point#Sequence_points_in_C_and_C++

Before a function is entered in a function call. The order in which the arguments are evaluated is not specified, but this sequence point means that all of their side effects are complete before the function is entered. In the expression f(i++) + g(j++) + h(k++), f is called with a parameter of the original value of i, but i is incremented before entering the body of f. Similarly, j and k are updated before entering g and h respectively. However, it is not specified in which order f(), g(), h() are executed, nor in which order i, j, k are incremented. If the body of f accesses the variables j and k, it might find both, neither, or just one of them to have been incremented. (The function call f(a,b,c) is not a use of the comma operator; the order of evaluation for a, b, and c is unspecified.)

The operators ++, → have same precedence so the associativity will come into the picture, L → R in this case.

Again let’s change some variables name to avoid confusion.

    struct myst{
char a[20];
char *b;
struct myst *p;
}x[2] = {"GATE", "Overflow", x+1, "GO", "Classes", x}, *ptr = x;
    printf("%s", ptr++->p->b++);

‘p’ is a member(child) variable and can not be accessed without accessing it’s parent (x[0], x[1] in this case)(I don’t think C has parent child terminology I used that just for understanding).

The original value ‘ptr’ will be used and incremented later.

ptr → p is effectively same as saying x[0].p which is a pointer to the second (1-th) element of x.

ptr → p → b is the pointer to string literal “Classes” .

Side effects:

ptr = ptr + 1 * sizeof(*ptr). which is the address of “x+1”. ptr now is pointing to the second (1-th) element of the array.

b = b + 1 * sizeof(b*): that now is pointing to the first element/base address of “lasses”.