简体   繁体   中英

Is it possible to manually calculate the byte-offset of a class member?

That is, what is the standard a compiler uses to generate a class? For example, let's say that I have class C with members x , y , and z , and I want to know the offset of z within that class. Can I just add up the data-type sizes of the other members, like I would for a structure?

No You cannot.
Compilers are free to align the members as they chose to.It is an implementation detail of the compilers.

If you're working with aPOD , then you can use the offsetof macro.

But If working with a Non-POD , then I suppose there won't be any portable method to do so.

You can do it programatically like this in a method of the class. Not generic but works.

offset = (unsigned char*)&(this->z) - (unsigned char*)this;

Full working example

#include <iostream>

class C
{
public:
    int x;
    char y;
    int z;
    size_t offset() const
    {
        return (unsigned char*)&(this->z) - (unsigned char*)this;
    }
};

int main()
{
    C c;
    std::cerr << "Offset(cast): " << c.offset() << "\n";
}

You can kind-of do this by calculating the offset using a sample object. (see @bert-jan's or @sodved's answer).

However, this is dangerous! You can't treat c++ classes and structs as the regular structures you imagine them to be.

The problem is that for any given pointer-to-an-object you are given, the offset might be different!

Why? because of subclassing and multiple inheritance, additional data may be placed in the class before the regular struct members. The amount of data may differ with each different subclass of your class.


See this question: Why can't you use offsetof on non-POD structures in C++? for more details.

you can use &(class_name::member_name) to get offset.

Definitely not per the standard. There are compiler specific solutions which can help you infer it, though.

Microsoft has this:

#pragma pack(push,1)
struct Foo {
  uint8 a;
  uint32 b;
};
#pragma pack(pop)

I can relay (only by hearsay) that GCC also supports this with an extension.

    #define _OFFSET(p_type, p_member) (size_t)(&((p_type *)NULL)->p_member)

    struct a
   {
       int a, b;
   };

   cout << _OFFSET(struct a, b); // output is your offset

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