简体   繁体   中英

how to calculate member offset in c++ class

example

class B {
public:
   int y;
private:
   int x;
};
class A : public B {
public:
   int a;
private:
   int b;
};

how to calculate Ab's offset in some object of A ?

one method was to use gdb, but it was slow.

is there other method works which don't need to execute/compile the program ?

how to calculate Ab's offset in some object of A ?

You can use the standard macro offsetof if the class is standard layout, or your language implementation supports it for non-standard layout classes (your class is not standard layout):

std::size_t offset = offsetof(A, b);

is there other method works which don't need to execute/compile the program ?

You could read the ABI specification of your language implementation. If you understand all of it, the calculation should be possible with basic addition and multiplication.

The simple cases are easy to calculate. The rules can be quite complex however and it may not be easy to accurately identify the cases which are simple.

Member's offset equals to

ptrdiff_t(&obj.member) - ptrdiff_t(&obj)

or inside of class' method, especially if your member is private, you may use

ptrdiff_t(&this->member) - ptrdiff_t(this)

The only thing to take into account is if there are virtual methods then members offsets are not 0-based. At 0-th offset there is usually pointer to virtual methods table. If there are no virtual methods then offsets are 0-based (0 is offset of first member of most base parent class), at least I never had non-0-based offsets for non-virtual classes.

Full example code:

Try it online!

#import <iostream>
#import <cstddef>
using namespace std;

class B {
public:
   int y;
private:
   int x;
};
class A : public B {
public:
   int a;
   ptrdiff_t off_b() const { return ptrdiff_t(&this->b) - ptrdiff_t(this); }
private:
   int b;
};

int main() {
    A obj;
    cout << obj.off_b() << endl;
    cout << ptrdiff_t(&obj.a) - ptrdiff_t(&obj) << endl;
    cout << ptrdiff_t(&obj.y) - ptrdiff_t(&obj) << endl;
    return 0;
}

Output:

12
8
0

Here is same code but with virtual methods . Members start at offset 8 inside this code run, but this offset may differ in different implementations.

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