Click here to Skip to main content
11,637,662 members (74,607 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
I was given this code to test my cpp understanding, and I am quite confused:

    #include "stdafx.h"
    #include <iostream>
    #include <cstddef>
    
    using namespace std;
    
    class A
    {
    public:
        A() : m_x(0) { }
    
    public:
        static ptrdiff_t member_offset(const A &a)
        {
            const char *p = reinterpret_cast<const char*>(&a);
            const char *q = reinterpret_cast<const char*>(&a.m_x);
    
            return q - p;
        }
    
    private:
        int m_x;
    };
    
    class B
        : public A
    {
    public:
        B() : m_x('a') { }
    
    public:
        static int m_n;
    
    public:
        static ptrdiff_t member_offset(const B &b)
        {
            const char *p = reinterpret_cast<const char*>(&b);
            const char *q = reinterpret_cast<const char*>(&b.m_x);
    
            return q - p;
        }
    
    private:
        char m_x;
    };
    
    int B::m_n = 1;
    
    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 _tmain(int argc, _TCHAR* argv[])
    {
    	A a;
        B b;
        C c;
        std::cout << ((A::member_offset(a) == 0) ? 0 : 1);
        std::cout << ((B::member_offset(b) == 0) ? 0 : 2);
        std::cout << ((A::member_offset(b) == 0) ? 0 : 3);
        std::cout << ((C::member_offset(c) == 0) ? 0 : 4);
        std::cout << std::endl;
    
        return 0;
    }

Why is the answer 0204?
Posted 19-Jan-13 1:51am
Comments
Mohibur Rashid at 19-Jan-13 8:00am
   
How about debugging? try debugging, you will know
DaveAuld at 19-Jan-13 8:00am
   
Have you stepped through and watched all the various variables? What about doing it with a pen and paper, step through line by line and write down what you think is happening.

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

On a typical implementation, the answer would be:

Since class A does not have any virtual functions, it will not have any vtable and since it does not derive from another class it first member will start at the same address as the class itself. This will give you the two 0 of your output (0204).

Since class B derives from class A, its members will be placed after those of the parent class in the layout. And since class A is not empty, then the offset will not be 0. It might have been 0 (depending on the compiler) if it was empty. This will give the 2 in your output.

For class C, the vtable could be placed before the data thus the data won't be at offset 0. This will give the 4 in your output.

Most of this is compiler and platform dependant and can vary depending according to selected compiler options (alignment, empty class optimization...)

By the way, you should avoid code that depends on the layout of a class whenever possible as it will not be portable.
  Permalink  
Comments
H.Brydon at 19-Jan-13 13:18pm
   
Agree with Philippe (+5).

The code also had endian issues too. This adds another mechanism for answers to be different on different platforms.
Sergey Alexandrovich Kryukov at 19-Jan-13 22:56pm
   
Nice explanation, good advice, a 5.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 309
1 stibee 288
2 OriginalGriff 285
3 jyo.net 250
4 Mika Wendelius 189
0 OriginalGriff 9,031
1 Sergey Alexandrovich Kryukov 8,763
2 Mika Wendelius 6,999
3 F-ES Sitecore 2,388
4 Suvendu Shekhar Giri 2,320


Advertise | Privacy | Mobile
Web03 | 2.8.150728.1 | Last Updated 19 Jan 2013
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100