Search code examples
c++alignmentpackingtype-traitscompile-time-constant

C++ class/structure data member offset as constant expression


Taking offset of a data member is as easy as this:

#define MEMBER_OFFSET(Type, Member) \
    ((unsigned long)(((char *)&((Type *)0)->Member) - (char *)0));

I want to make this a constant compile-time expression (or use type traits). For example, to use it to implement SFINAE based solutions using member offsets, use it static assertions etc.

UPDATE: The question is - how to make it a compile-time expression. Not whether it works with POD types, or is there a standard macro in C library etc.


Solution

  • Though I can't get what your compiler is, the following code can be compiled by VC8, ideone(gcc-4.3.4), and Comeau online:

    struct A { int i; };
    template< size_t > struct S;
    
    int main() {
      S< offsetof( A, i ) > *p;
    }
    

    Gcc has __offsetof__ extension. VC seems to have a capability to take a non-compile-time constant for a template argument strangely. As for Comeau, I have no idea about the internal of Comeau's offsetof unfortunately.

    Incidentally, though this won't answer your question directly, as for SFINAE purpose, since a member pointer constant can be used as a template argument and you can specialize on it, you can write as the following:

    struct A {
      int i, j;
    };
    
    template< int A::* > struct S;
    template<> struct S< &A::i > { static char const value = 'i'; };
    template<> struct S< &A::j > { static char const value = 'j'; };
    
    int main() {
      cout<< S< &A::i >::value <<endl;
      cout<< S< &A::j >::value <<endl;
    }
    

    Hope this helps.