The MSVC compiler uses different sizes for pointers to member functions as an optimization. This optimization violates the Standard. Kudos to Igor Tandetnik mentioning reinterpret_cast
in a MSDN form post, [expr.reinterpret.cast]p10
A prvalue of type “pointer to member of X
of type T1
” can be
explicitly converted to a prvalue of a different type “pointer to
member of Y
of type T2
” if T1
and T2
are both function types
or both object types. The null member pointer value is converted to
the null member pointer value of the destination type. The result of
this conversion is unspecified, except in the following cases:
- converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original
type yields the original pointer to member value.
So there's a roundtrip guarantee, this effectively forces conforming implementations to use the same size for all pointer to member function types.
The MSVC optimization is performed if the /vmb
switch is set. For the case of single inheritance, the optimised pointer to member function requires only a void*
-sized storage, see The Old New Thing: Pointers to member functions are very strange animals.
If you only forward-declare the type CL
and then form a pointer-to-member function, the optimization hopefully is deactivated (I could not find any documentation on that, unfortunately). Otherwise, you might get inconsistent sizes before and after the definition of CL
.
By the way, you can get inconsistent sizes for enumerations in VS2010, if you forward-declare them without specifying an underlying type and later explicitly define the underlying type for the definition of the enum. This works only with language extensions activated.