Given a variable foo of type FooClass* and a member variable in that class named bar, is the distance between foo and &(foo->bar) the same in any situation with some constraints:
-
FooClassis a non-POD type. -
We know that
foowill always point to an instance ofFooClass, and not some subtype of it. -
We only care about behaviour under a single compiler and a single compilation; that is, the value this may result in under gcc is never used in code compiled with MSVC, and it is never saved to be re-used between compilations. It is computed in the binary and used in the binary, and that is it.
-
We don’t use a custom
new, although some instances of the class may be stack-allocated and some heap-allocated. -
There is no explicit
ctorforFooClass; it relies upon the compiler-generated one (and each of the fields inFooClassis either POD or default-constructable).
I can’t find a guarantee either way on this in the standard (nor did I expect to), but my rudimentary testing with gcc leads me to believe that it will always be the case there. I also know that this guarantee is made for POD-types, but let us assume this type can’t be POD.
An update/clarification: this is just for a single compilation of a single binary; the calculated offsets will never leave that single execution. Basically, I want to be able to uniquely identify the fields of a class in a static map and then be able to lookup into that map for some macro/template/EVIL trickery. It is merely for my own amusement, and no life support machines will rely on this code.
After you have compiled your program, Yes*.
The offset will remain constant.
There is one very important restriction, however: foo must be pointing specifically to a FooClass object. Not a class derived from FooClass, or anything else for that matter.
The reason that C++ makes the POD distinction regarding member offsets is because both multiple inheritance and the location (or lack of) a vtable pointer can create situations where the address of an object is not the same as the address of that object’s base.