I don't understand why adding a forward declaration for a class changes a size of its pointer to member type
#include <iostream>
using namespace std;
int main()
{
//struct CL;
//cout<<sizeof(int (CL::*)())<<endl;
struct CL{};
cout<<sizeof(int (CL::*)())<<endl;
}
output VS2013:
4
But if I uncomment the first two lines in main(), then the output is different:
16
16
So, only a simple adding a forward declaration before a definition of struct CL increases a size of a pointer to member of CL. Why? I know that a size of member function pointer depends by structure of a type (e.g. virtual functions and base classes may increase it), but why can the sizeof operator be applied to a pointer to member of an incomplete type? Or it can't? I have not found it in the Standard
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]p10So 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 avoid*
-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 ofCL
.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.