NPS
NPS

Reputation: 6355

Position of a vpointer in an object

class C
{
public:
    C() : m_x(0) { }
    virtual ~C() { }

public:
    static ptrdiff_t member_offset(const C &c)
    {
        const char *p = reinterpret_cast<const char*>(&c);
        const char *q = reinterpret_cast<const char*>(&c.m_x);

        return q - p;
    }

private:
    int m_x;
};

int main(void)
{
    C c;
    std::cout << ((C::member_offset(c) == 0) ? 0 : 1);
    std::cout << std::endl;

    std::system("pause");
    return 0;
}

The program above outputs 1. What it does is just check the addresses of the c object and the c's field m_x. It prints out 1 which means the addresses are not equal. My guess is that is because the d'tor is virtual so the compiler has to create a vtable for the class and put a vpointer in the class's object. If I'm already wrong please correct me.

Apparently, it puts the vpointer at the beginning of the object, pushing the m_x field farther and thus giving it a different address. Is that the case? If so does the standard specify vpointer's position in the object? According to wiki it's implementation-dependent. And its position may change the output of the program.

So can you always predict the output of this program without specifying the target platform?

Upvotes: 1

Views: 376

Answers (3)

Mats Petersson
Mats Petersson

Reputation: 129454

In reality, it is NEARLY ALWAYS laid out in this way. However, the C++ standard allows whatever works to be used. And I can imagine several solutions that doesn't REQUIRE the above to be true - although they would perhaps not work well as a real solution.

Note however that you can have more than one vptr/vtable for an object if you have multiple inheritance.

Upvotes: 3

NPE
NPE

Reputation: 500663

Yes, it is implementation dependent and no, you can't predict the program's output without knowing the target platform/compiler.

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 477338

There are no "vpointers" in C++. The implementation of polymorphism and dynamic dispatch is left to the compiler, and the resulting class layout is not in any way specified. Certainly an object of polymorphic type will have to carry some extra state in order to identify the concrete type when given only a view of a base subobject.

Implementations with vtables and vptrs are common and popular, and putting the vptr at the beginning of the class means that you don't need any pointer adjustments for single inheritance up and downcasts.

Many C++ compilers follow (parts of) the Itanium ABI for C++, which specifies class layout decisions like this. This popular article may also provide some insights.

Upvotes: 3

Related Questions