简体   繁体   中英

In C++ should derived class pointer point to base class pointer?

I've very rare error and to understand the reason I need to know some facts of C++. Let me explain the problem:

There is such structure:

struct Base;                 // not polimorfic
class Derived : public Base; // has pure virtual
class ImplDerived : public Derived    // implements pure virtuals

some_function(Base* base);
int main() {
    ImplDerived impd;
    some_function(&impd);
}

Now, what's happening is this:

  • Running on desktop linux environment:

    No error.

    Inside some_function , base pointer points to the same address of &impd . In other words, in memory, ImplDerived object starts with Base object. ie, when I'm debugging, I see this:

     ImplDerived : 0xab00 -> Derived : 0xab00 -> Base : 0xab00 
  • Running on embedded linux in embedded device (compiled with its compiler):

    Error.

    Inside some_function , base pointer points again to &impd .

    However, this time it is not the right place where base is. Because now
    base starts at &impd +4 bytes.

    When I'm debugging I see this:

     ImplDerived : 0xab00 -> Derived : 0xab00 -> Base : 0xab04 

Questions:

  • AFAIK, the offset between base and derived pointer is permittible, right ?

  • If it is, then should not the implicit casting when passing the pointer to the some_function find where the base is?

  • If it should, then would it be some error in compilation?

Thanks.

Compilers:

  • Desktop: gcc 4.9.2-10 Debian 64 bits
  • Embedded: gcc 4.8.0

EDIT (RESULT):

After all tests, we have decided that this is a compiler error. Casting just does not work correctly, i) for non-polymorphic base, ii) for multiple inheritance.

No, pointers to base and derived classes do not have to match. Especially this happens when multiple inheritance is used. In your case the reason seems different. Because the base class is not polymorphic, it does not have a virtual table pointer as its hidden member. However, the polymorphic derived classes start to have virtual table pointer. I guess you are compiling in 32-bit, so that's where 4 bytes offset arises: that pointer is 32-bit.

dynamic_cast should solve your problem.

AFAIK, the offset between base and derived pointer is permittible, right?

It is permitted, yes. In fact, it's mandatory if the derived class has multiple (non-empty) base classes, since all of the base class sub objects cannot share the same address. But even a sole base class sub object might not share the derived object's address, as you have observed.

If it is, then should not the implicit casting when passing the pointer to the some_function find where the base is?

Yes. When the derived pointer is implicitly converted to the base pointer, it should be pointing to the base sub object.

If it should, then would it be some error in compilation?

Maybe, the example code should be just fine, but it's incomplete.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM