问题
There was a bug in g++-4.1 and prior which made it reject the following valid program:
struct S { int n; };
unsigned long long f() { return sizeof S::n; }
// ^--g++-4.1 "error: invalid use of non-static data member 'S::n'"
int main() {}
I need to write portable code to be compiled (among others) with this old version of g++, so I came up with the following:
#define sizeofmember(type, member) sizeof(static_cast<type*>(0)->member)
unsigned long long f() { return sizeofmember(S,n); }
I know that the crafted type*
NULL pointer won't be dereferenced, because of:
[expr.sizeof]/1
The
sizeof
operator yields the number of bytes occupied by [...] the type of its operand. The operand is either an expression, which is an unevaluated operand ([expr.prop]), or a parenthesized type-id.[expr.context]/1
In some contexts, unevaluated operands appear ([expr.prim.req], [expr.typeid], [expr.sizeof], [expr.unary.noexcept], [dcl.type.simple], [temp]). An unevaluated operand is not evaluated. [ Note: In an unevaluated operand, a non-static class member may be named ([expr.prim.id]) and naming of objects or functions does not, by itself, require that a definition be provided ([basic.def.odr]). An unevaluated operand is considered a full-expression. — end note ]
But is it valid though? From C++98 to C++14?
来源:https://stackoverflow.com/questions/51597864/get-the-size-of-a-member-variable