开发者

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? 开发者_StackOverflow社区 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 a POD, 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.


Have you tried offsetof()?

http://www.cplusplus.com/reference/clibrary/cstddef/offsetof/


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜