0

In the code, child is casted to type Parent, and passed to parentMove. child does not have members x and y. How does parentMove access child.parent.x and child.parent.y? How does type casting work here? Thx

#include <stdio.h>

typedef struct{
    int x, y;
    int (*move)();
}Parent;

typedef struct {
    Parent parent;
    int h, w;
}Child;

int parentMove(Parent* parent, int y, int x){
    parent->y+=y;
    parent->x+=x;
    printf("%d %d", parent->y, parent->x);
    return 1;
}

int main(void) {
    Parent parent = {.x = 2, .y = 1, .move = &parentMove};
    Child child = {.parent = parent, .h = 3, .w = 4};
    ((Parent*)(&child))->move((Parent*)&child, 10, 10);
    return 0;
}
4
  • 2
    See Is pointer to struct a pointer to its first member?. &child == &child.parent and the latter is a Parent * which is why the cast works. Commented Nov 16, 2020 at 8:28
  • 1
    int (*move)(); should be int (*move)(Parent* parent, int y, int x);, is it omitted intentionally? Commented Nov 16, 2020 at 8:42
  • @csavvy I know it works so I just omitted it intentionally. Well it's a bad habit though Commented Nov 16, 2020 at 8:45
  • 2
    @Austin AFIK that's UB. So it does not work. It just behaves like it does. Commented Nov 16, 2020 at 8:55

2 Answers 2

1

How does parentMove access child.parent.x and child.parent.y?

It doesn't know about the child part. It doesn't matter if a Parent object is declared as a stand-alone object or as a member of Child, same thing applies in either case.

How does type casting work here?

Poorly... you have implemented inheritance incorrectly if you have to cast to the base class from the caller side. It would seem that Child should have implemented its own move that takes a Child* as parameter, if only to make it a wrapper to the parent.

Sign up to request clarification or add additional context in comments.

Comments

0

How does type casting work here?How does parentMove access child.parent.x and child.parent.y?

In child structure, the first member is the parent structure, so internally memory representation of child structure is --

{
    {
        int x;         [ .. 4bytes .. ]
        int y;         [ .. 4bytes .. ]
        int *move();   [ .. 4bytes .. ]
    }
    int h;             [ .. 4bytes .. ]
    int w;             [ .. 4bytes .. ]
}

When you access parent.x , It is nothing but accessing first 4 bytes from starting address (i.e. &parent ). Similarly accessing parent.y means accessing 4 bytes after 4 bytes offset from starting address.

So when you pass address of child structure as a pointer to parent structure, the child-address actually points to a valid parent structure member inside, in the sense accessing first 4 bytes from the child-address is actually parent.x similarly other members of the contained parent structure are properly be accessed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.