2

There are multiple questions pretty similiar to this one with the difference that there sizeof(Base) != sizeof(Derived). That won't work for obvious reasons (the subscript operator applied on the pointer is relative to the pointees size, not to the actual unterlying type). However, I was wondering whether this code would be correct or not:

struct Base
{
    int Data;
};
struct Derived : public Base
{
};
int main()
{
    static_assert(sizeof(Base) == sizeof(Derived), "Sizes are not equal");

    Derived Data[10];
    Base* Ptr = Data;
    Ptr[3].Data = 5;
}

Obviously, Ptr[3] won't access any half ripped Base instances anymore since the sizes are equal, but is the code still correct?

1
  • The language does not guarantee that the sizes are equal. If you guarantee that, then yes, it looks legal (doesn't mean you should). Commented Oct 23, 2014 at 13:38

4 Answers 4

1

Yes, this is correct (in the sense of well-defined, not necessarily sane) since the two classes are layout-compatible - they are standard-layout structs with the same non-static data members.

It's very fragile though; small changes to the classes could break the compatibility and give undefined behaviour.

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

2 Comments

Is it still well-defined if Base has some virtual methods that Derived overrides (with the size still staying the same)?
@Conclusio: no, if a class has virtual functions then it isn't standard layout.
1

Let's suppose we have a function that receives a Derived

double foo(Derived d);

Now consider a slight variation of your code:

Derived Data[10];
Base* Ptr = Data;
Base myB;
Ptr[3] = myB;

Essentially we have put a Base object into the Data array. We then call

foo(Data[3]);

Lo and behold we have tricked foo into receiving a Base

This is the reason you should not treat an array of Derived as an array of Base. It is not only the issue of size.

1 Comment

This has nothing to do with arrays. You can do the same if you replace Data with a single Derived object.
0

Lets consider following lines:

Derived Data[10];
Base* Ptr = Data;

Data holds an address of first element of array. So, it is a pointer of type Derived*. There is a static cast from Derived* to Base*. That means that code is correct.

1 Comment

Yes, that's obviously correct and I know that. But that wasn't the question, the core of the question was whether the subsequent subscript operator applied on the pointer is correct or not.
0

this is correct but not generally done because when pointer of derived class points to object of base, there is chance of data corruption.

1 Comment

But it is still correct. Anything else does not matter here :)

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.