Home > Net >  C class/struct member offset as constexpr?
C class/struct member offset as constexpr?

Time:12-15

The following construct in main() retrieves a class member's offset at runtime:

struct Base
{
  virtual ~Base() = default;
};

struct Cls : public virtual Base
{
  int a, b;
};



int main()
{
  int Cls::* ptr = &Cls::a;

  unsigned long offset = *reinterpret_cast<unsigned long*>(&ptr);
}

The class layout is determined at compile time and doesn't change. So, it would be beneficial to make this a constexpr.

Unfortunately, the above assignment requires an lvalue.

How can I get the same result using a constexpr?

CodePudding user response:

Your class is not standard-layout. There is no way to obtain an offset to a member of a non-standard-layout class without undefined behavior (and therefore certainly not in a compile-time context) that is guaranteed by the standard.

Your approach is definitively UB per standard, even in a standard-layout class. It relies on very specific implementation details, assuming it works in the first place. (I haven't tested it.)

Since C 17 use of the offsetof macro is conditionally-supported (also in a compile-time context) for non-standard-layout classes. If the compiler does not support this, then what you want to do is impossible (except maybe via other compiler extensions).

CodePudding user response:

Found the solution myself:

template<class T> constexpr unsigned long Offset(T ptr)
{
    return *reinterpret_cast<unsigned long*>(&ptr);
}
  • Related