CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Deploying Windows Server 2008 with System Center
  • Remote Desktop Protocol Performance Improvements in Windows Server 2008 R2 and Windows 7
  • The Microsoft Dynamics CRM Security Model
  • SQL Server Modeling Services with Microsoft Visual Studio 2010 Beta 2

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > Visual C++ Programming
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    Visual C++ Programming Ask questions about Windows programming with Visual C++ and help others by answering their questions.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old November 25th, 2009, 10:56 PM
    abhaykumar abhaykumar is offline
    Junior Member
     
    Join Date: Nov 2009
    Location: India
    Posts: 9
    abhaykumar is an unknown quantity at this point (<10)
    [RESOLVED] calculating Offset of class

    See the code snippet below:

    //===========================================
    class Base1 {
    public:
    virtual void f() { }
    };
    class Base2 {
    public:
    virtual void f() { }
    };
    class Base3 {
    public:
    virtual void f() { }
    };

    class Drive : public Base1, public Base2, public Base3 {
    };

    #define _ATL_PACKING 8

    #define offsetofclass(base, derived) \
    ((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING)

    int main() {
    cout << offsetofclass(Base1, Drive) << endl;
    cout << offsetofclass(Base2, Drive) << endl;
    cout << offsetofclass(Base3, Drive) << endl;
    return 0;
    }

    //==============================================
    //output is:
    //0
    //4
    //8

    I really don't understand that how the macro calculates the offset. Please describe it in detail. Furthermore, from MSDN, I don't get much about static_cast or other cast types. Does it play the main role here? What about replacing static_cast with reinterpret_cast or dynamic_cast? Please clear them.

    Any help would be highly appreciated.
    Thank you.
    Reply With Quote
      #2    
    Old November 26th, 2009, 12:02 AM
    GeoRanger's Avatar
    GeoRanger GeoRanger is offline
    Member
     
    Join Date: Mar 2006
    Posts: 28
    GeoRanger is on a distinguished road (10+)
    Re: calculating Offset of class

    First you need to be familiar with how your class is layed out in compiled code. Sans multiple inheritance, the first compiler-supplied member of your class is a pointer to the v-table. A pointer to an instance of your class will contain the location in memory where the instance's pointer to the v-table sits. (Though that is compiler dependent.)

    With multiple inheritance, your class has multiple v-table pointers because each base class implies a v-table different from that of the others. These pointers are listed one-after-another at the start of your class. A pointer to your derived class will have the same memory address as the first of those v-table pointers. However, if you cast your pointer to one of its bases, the address will change to the place in memory where the pointer to that class's v-table is stored.

    Now for the macro. The _ATL_PACKING defintion is somewhat arbitrary. It could probably be any number divisible by 4 and should probably be changed to sizeof(void *) to be compatible with 64-bit systems. The first step of the macro
    Code:
    (derived*)_ATL_PACKING
    is tricking (for lack of a better word) the compiler into thinking that an instance of the derived class sits at memory address 8. The next step
    Code:
    static_cast<base *>()
    is causing the switch mentioned above to the seating location of the v-table pointer for one of the base classes. This will be 8 + sizeof(void *) * (index of base class v-table pointer). The next cast
    Code:
    (DWORD)
    is converting that memory address into an integer value for the purpose of mathematical manipulation, namely
    Code:
    -_ATL_PACKING
    which is taking the difference between two memory address. Voila! This gives you the offset from the start in memory of your derived class to the address where the v-table pointer for a base class of particular interest sits.

    * reinterpret_cast is for casting one kind of pointer into another
    * dynamic_cast only works if RTTI is turned on and will attempt the cast of a base type to a derived type
    * static_cast is basically a general cast, but is much safer than a C-Style cast
    * const_cast is usually used as a band-aid in poorly-written code (where member functions which were not declared const but should have been) which needs to use better-written code which has used const appropriately. const_cast is also used to remove "volatile".
    * C-Style cast (used twice in the macro) weakens static analysis but is sometimes necessary (as in the macro)

    Hope this helps

    Last edited by GeoRanger; November 26th, 2009 at 12:19 AM. Reason: Forgot to mention cost_cast
    Reply With Quote
      #3    
    Old November 26th, 2009, 01:36 AM
    abhaykumar abhaykumar is offline
    Junior Member
     
    Join Date: Nov 2009
    Location: India
    Posts: 9
    abhaykumar is an unknown quantity at this point (<10)
    Re: calculating Offset of class

    Thank you very much for your support. Now I got the idea behind that macro.
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > Visual C++ Programming


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 02:13 PM.



    Acceptable Use Policy


    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.