Trick for the data
Your trick is based on assumptions on the memory layout of your object. Fortunately for your specifi example , with your compiler, it seems to work.
If I compile this code with MSVC2013 it doesn't work at all !! I could eventually find out that it works when I use an array of short
instead of int
, if I'd put some hints in the constructor:
A(int t) { a = t; cout << "A: " << (void*)this << " a: " << (void*)&a << " rel:" << (char*)&a - (char*)this << endl; }
Conclusion: You can't rely on this in general (an not even for your compiler in more complex examples). The standard gives very limited ensurance about relative memory addresses of members:
Section 9.2/15: Nonstatic data members of a (non-union) class with the
same access control are allocated so that later members have higher
addresses within a class object. The order of allocation of non-static data
members with different access control is unspecified. Implementation
alignment requirements might cause two adjacent members not to be
allocated immediately after each other; (...)
In addition your trick might create pointer aliasing. So the compiler makes assumption about your pointers and the members of your object which might not be valid, causing generated optimisations to fail.
Trick for the functions
For the address of your function, it's even worse. This again is not defined in the standard and is implementation specific.
The commonly used implementation for virtual functions is base on class specific vtables. Each polymorphic object has somewhere in the class a pointer to its vtable (usually in the first fewbytes of the object.
The relative position of function pointer in the vtable depends on all the virtual functions of the class and all the inherited classes. For your example, with MSVC2013 I could manage to call the function:
typedef int (A::*fptr)();
fptr pf = (*(fptr**)x)[0]; // first unction in vtable
(x->*pf)(); // call it.
But of course this is totally non-standard and extremely dangerous !
And keep in mind that for non virtual functions, you can't get the address from the object at all.