From the C++ standard:
A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members, — has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member
The macro offsetof(type, member-designator) accepts a restricted set of type arguments in this International Standard. If type is not a standard-layout class (Clause 9), the results are undefined
Considering these statements is there any safe way of using offsetof
for members that depend on template parameters? If not, how may I get the offset of a member in template classes? What might be unsafe when using something like:
//MS Visual Studio 2013 definition
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
on non standard layout classes?
Following a sample where is NOT SAFE according to the standard:
#include <cstddef>
#include <iostream>
template<typename T>
struct Test
{
int a;
T b;
};
struct NonStdLayout
{
virtual void f(){};
};
int main()
{
std::cout << offsetof(Test<int>, b) << std::endl;
std::cout << offsetof(Test<NonStdLayout>, b) << std::endl;
return 0;
}