0
    class A {
    public: 
        int a = 5;
        int geta(){return a;}
};

class B : public A {
    public:
        int b = 6;
        int getb(){return b;}
};

int main(){
    A a;
    B* b = (B*) &a;
    cout<<b->geta()<<endl;   
    cout<<b->getb();
}

Output: 5
5

Questions: why does both giving same results?
How does casting works internally ?

currently I am using: Thread model: win32

gcc version 9.2.0 (GCC)

rog
  • 93
  • 9
  • 2
    when you do invalid things, expect the unexpected. – Abel May 18 '21 at 12:58
  • this only "works" with a very lax definition of "works". The rule of thumb with c-style casts: If you cannot replace it with a proper C++ cast, it very likely is not doing what you think it does. – 463035818_is_not_an_ai May 18 '21 at 12:58
  • 2
    @largest_prime_is_463035818 technically, you can replace this c-cast with c++ cast - it is `static_cast`. – SergeyA May 18 '21 at 13:02
  • It's not even sure that both methods will give the same result: https://godbolt.org/z/Yx7TocM5x – m88 May 18 '21 at 13:04
  • You say "trust me, there really is a `B` instance here", and the compiler believes you. And sometimes weird things happen when you lie. – molbdnilo May 18 '21 at 13:05
  • @Abel That's a good start. But I would add that also don't assume that there would be unexpected things. Lack of unexpected things doesn't mean that you haven't done invalid things. – eerorika May 18 '21 at 13:09
  • @SergeyA d'oh, right. I could argue that `dynamic_cast` is the proper one here, but thats just making excuses. C++ casts are as error prone as c-casts, they are just easier to spot (and harder to type, which makes me think twice, but I didn't while writing the comment ;) – 463035818_is_not_an_ai May 18 '21 at 13:10
  • @largest_prime_is_463035818 `C++ casts are as error prone as c-casts` not "as" error prone. Both are error prone, but C-style casts are definitely more error prone. So, it's good to advice against C-style casts as you did, even though in this case the C-styleness of the cast wasn't the core of the problem – eerorika May 18 '21 at 13:34
  • @eerorika The lack of unexpected things is the only basis we have in the real world. The process called validation is built upon a lack of unexpected things meaning something is valid (for a specific case). This goes for the very hardware your code runs on and is not something one can easily shake. – Abel May 19 '21 at 13:30

2 Answers2

5

why does both giving same results?

Because the behaviour of the program is undefined.

How does casting works internally ?

This cast doesn't "work". The behaviour of the program is undefined.


Some extra explanation.

(B*) &a

This here is a C style cast. Don't use C style casts. It can mean different things in different contexts. In this case, it means a static cast from the base class pointer to a derived class pointer.

When you static cast to a derived type that isn't the dynamic type (or a base of the dynamic type) of the object, the behaviour of the program is undefined. Don't downcast to a type that isn't the dynamic type (or base) of the object.

If you don't know what the dynamic type is1, then dynamic_cast is a safer option, since you can check for null in case your guess was wrong. That said, if you need to down cast without knowing the derived type, then your design is likely bad and you probably should have been writing a virtual function instead.

Another rule of thumb: If you don't know what you're doing, then adding casting will create problems for you. Study what casting means before using it at random.

1 This is a hypothetical discussion about where a downcast might be used. In this case you should know that the dynamic type isn't the one that you're casting to, so any cast to that type would be pointless.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

Answering question How does casting works internally ? as it seems to be missed by another answer.

Internally, your c-style cast is treated with static_cast. static_cast down the hierarchy is only allowed when the dynamic type of the object being pointer (or referenced) to matches the cast. In your case, it does not - the dynamic type of the object is still A.

But the static_cast doesn't really check for dynamic object type (this is while it is called static), it allows programmer to basically say: "Trust me, I know what I am doing". So compiler obliges and believes you, and generates code which would work correctly in assumption that dynamic type is what you tell it is.

In your case, though, it is not - so compiled program behaves unexpectedly.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • Seems like I need to learn principles of casting first. Do you know any book or article which explains dynamic and static cast and their internal implementation? – rog May 18 '21 at 13:57
  • 1
    @rog I suggest you start with this list: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – SergeyA May 18 '21 at 13:59