#include <iostream>
using namespace std;
#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)
struct MyStruct {
int var1;
long var2;
double var3;
unsigned char L;
int a;
int b;
int c;
};
int main() {
cout << "offset of a = " << (int)asOFFSET(MyStruct,a);
}
// I have found this as the approach to calculate the position offset of any item `m` of any struct `s` // from the beginning of the structure.
//The macro is (most likely) used by the scripting library to find out the internal layout of a class's
// members without making assumptions about its type, architecture or inheritance model.
// For most C++ programs, this information (memory layout) should ideally not be needed at all.
// But in the off chance that you do need it (e.g. if you're writing an analyser / debugger), you would be
// better off retaining this macro as-is
// The purpose of the macro is to determine, given *any* name of a struct and *any* name of a
// member of that struct, the *distance in memory* from the beginning of an arbitrary instance of
// the struct, and the location of that member in the same instance.
//`m` does not have a "type", and neither does `s`. The *entire concept of "type" goes out the
// window* when you use macros. This stuff simply *is not C++*; it's basically a completely
// separate language that's used to edit C++ code in-place. When the preprocessor runs,
//`asOFFSET(MyStruct, a)` will be *literally replaced with the text* `((size_t)
// (&reinterpret_cast<MyStruct*>(100000)->a)-100000)` before the compiler even begins its work.
// `((size_t)(&reinterpret_cast<MyStruct*>(100000)->a)-100000)` is intended to evaluate to 0,
// because the `a` member of `MyStruct` instances appears at the beginning of each instance. I'm
// not actually 100% sure that this is legal behaviour per the specification, but the intent is as
// follows:
// * Pretend that there is an instance of `MyStruct` at the memory location `100000`, by treating the
// number `100000` as if it were a pointer to a `MyStruct`.
// * Get the address in memory of the `a` member of this fake struct, and subtract `100000` again.
// That gives us the distance from the beginning of the fake struct to the specified member of that
// fake struct.
// * Cast that numeric value back to `size_t` (the numeric type used for measuring memory
// allocations, an unsigned integer type).
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBhc09GRlNFVChzLG0pICgoc2l6ZV90KSgmcmVpbnRlcnByZXRfY2FzdDxzKj4oMTAwMDAwKS0+bSktMTAwMDAwKQoKc3RydWN0IE15U3RydWN0IHsKIGludCB2YXIxOyAKIGxvbmcgdmFyMjsgCiBkb3VibGUgdmFyMzsKIHVuc2lnbmVkIGNoYXIgTDsKIGludCBhOwogaW50IGI7CiBpbnQgYzsKIAp9OwoKaW50IG1haW4oKSB7CgoKIGNvdXQgPDwgIm9mZnNldCBvZiBhID0gIiA8PCAoaW50KWFzT0ZGU0VUKE15U3RydWN0LGEpOwoKfQoKLy8gSSBoYXZlIGZvdW5kIHRoaXMgYXMgdGhlIGFwcHJvYWNoIHRvIGNhbGN1bGF0ZSB0aGUgcG9zaXRpb24gb2Zmc2V0IG9mIGFueSBpdGVtIGBtYCBvZiBhbnkgc3RydWN0IGBzYCAvLyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cnVjdHVyZS4KLy9UaGUgbWFjcm8gaXMgKG1vc3QgbGlrZWx5KSB1c2VkIGJ5IHRoZSBzY3JpcHRpbmcgbGlicmFyeSB0byBmaW5kIG91dCB0aGUgaW50ZXJuYWwgbGF5b3V0IG9mIGEgY2xhc3MncyAKLy8gbWVtYmVycyB3aXRob3V0IG1ha2luZyBhc3N1bXB0aW9ucyBhYm91dCBpdHMgdHlwZSwgYXJjaGl0ZWN0dXJlIG9yIGluaGVyaXRhbmNlIG1vZGVsLgoKCi8vIEZvciBtb3N0IEMrKyBwcm9ncmFtcywgdGhpcyBpbmZvcm1hdGlvbiAobWVtb3J5IGxheW91dCkgc2hvdWxkIGlkZWFsbHkgbm90IGJlIG5lZWRlZCBhdCBhbGwuIAovLyBCdXQgIGluIHRoZSBvZmYgY2hhbmNlIHRoYXQgeW91IGRvIG5lZWQgaXQgKGUuZy4gaWYgeW91J3JlIHdyaXRpbmcgYW4gYW5hbHlzZXIgLyBkZWJ1Z2dlciksIHlvdSB3b3VsZCBiZSAKLy8gYmV0dGVyIG9mZiByZXRhaW5pbmcgdGhpcyBtYWNybyBhcy1pcyAKCi8vIFRoZSBwdXJwb3NlIG9mIHRoZSBtYWNybyBpcyB0byBkZXRlcm1pbmUsIGdpdmVuICphbnkqIG5hbWUgb2YgYSBzdHJ1Y3QgYW5kICphbnkqIG5hbWUgb2YgYSAKLy8gbWVtYmVyIG9mIHRoYXQgc3RydWN0LCB0aGUgKmRpc3RhbmNlIGluIG1lbW9yeSogZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGFuIGFyYml0cmFyeSBpbnN0YW5jZSBvZiAKLy8gdGhlIHN0cnVjdCwgYW5kIHRoZSBsb2NhdGlvbiBvZiB0aGF0IG1lbWJlciBpbiB0aGUgc2FtZSBpbnN0YW5jZS4KCi8vYG1gIGRvZXMgbm90IGhhdmUgYSAidHlwZSIsIGFuZCBuZWl0aGVyIGRvZXMgYHNgLiBUaGUgKmVudGlyZSBjb25jZXB0IG9mICJ0eXBlIiBnb2VzIG91dCB0aGUgCi8vIHdpbmRvdyogd2hlbiB5b3UgdXNlIG1hY3Jvcy4gVGhpcyBzdHVmZiBzaW1wbHkgKmlzIG5vdCBDKysqOyBpdCdzIGJhc2ljYWxseSBhIGNvbXBsZXRlbHkgCi8vIHNlcGFyYXRlIGxhbmd1YWdlIHRoYXQncyB1c2VkIHRvIGVkaXQgQysrIGNvZGUgaW4tcGxhY2UuIFdoZW4gdGhlIHByZXByb2Nlc3NvciBydW5zLCAKLy9gYXNPRkZTRVQoTXlTdHJ1Y3QsIGEpYCB3aWxsIGJlICpsaXRlcmFsbHkgcmVwbGFjZWQgd2l0aCB0aGUgdGV4dCogYCgoc2l6ZV90KQovLyAoJnJlaW50ZXJwcmV0X2Nhc3Q8TXlTdHJ1Y3QqPigxMDAwMDApLT5hKS0xMDAwMDApYCBiZWZvcmUgdGhlIGNvbXBpbGVyIGV2ZW4gYmVnaW5zIGl0cyB3b3JrLgoKLy8gYCgoc2l6ZV90KSgmcmVpbnRlcnByZXRfY2FzdDxNeVN0cnVjdCo+KDEwMDAwMCktPmEpLTEwMDAwMClgIGlzIGludGVuZGVkIHRvIGV2YWx1YXRlIHRvIDAsIAovLyBiZWNhdXNlIHRoZSBgYWAgbWVtYmVyIG9mIGBNeVN0cnVjdGAgaW5zdGFuY2VzIGFwcGVhcnMgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIGluc3RhbmNlLiBJJ20gCi8vIG5vdCBhY3R1YWxseSAxMDAlIHN1cmUgdGhhdCB0aGlzIGlzIGxlZ2FsIGJlaGF2aW91ciBwZXIgdGhlIHNwZWNpZmljYXRpb24sIGJ1dCB0aGUgaW50ZW50IGlzIGFzIAovLyBmb2xsb3dzOgoKLy8gKiBQcmV0ZW5kIHRoYXQgdGhlcmUgaXMgYW4gaW5zdGFuY2Ugb2YgYE15U3RydWN0YCBhdCB0aGUgbWVtb3J5IGxvY2F0aW9uIGAxMDAwMDBgLCBieSB0cmVhdGluZyB0aGUgCi8vIG51bWJlciBgMTAwMDAwYCBhcyBpZiBpdCB3ZXJlIGEgcG9pbnRlciB0byBhIGBNeVN0cnVjdGAuCgovLyAqIEdldCB0aGUgYWRkcmVzcyBpbiBtZW1vcnkgb2YgdGhlIGBhYCBtZW1iZXIgb2YgdGhpcyBmYWtlIHN0cnVjdCwgYW5kIHN1YnRyYWN0IGAxMDAwMDBgIGFnYWluLiAKLy8gVGhhdCBnaXZlcyB1cyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmYWtlIHN0cnVjdCB0byB0aGUgc3BlY2lmaWVkIG1lbWJlciBvZiB0aGF0IAovLyBmYWtlIHN0cnVjdC4KCi8vICogQ2FzdCB0aGF0IG51bWVyaWMgdmFsdWUgYmFjayB0byBgc2l6ZV90YCAodGhlIG51bWVyaWMgdHlwZSB1c2VkIGZvciBtZWFzdXJpbmcgbWVtb3J5IAovLyBhbGxvY2F0aW9ucywgYW4gdW5zaWduZWQgaW50ZWdlciB0eXBlKS4K