[英]pointer to member function of incomplete type
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: 输出VS2013:
4 4
But if I uncomment the first two lines in main(), then the output is different: 但是如果我取消注释main()中的前两行,那么输出是不同的:
16 16
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. 因此,在struct CL的定义之前只添加一个前向声明只会增加指向CL成员的指针的大小。 Why?
为什么? I know that a size of member function pointer depends by structure of a type (eg 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?
我知道成员函数指针的大小取决于类型的结构(例如,虚函数和基类可能会增加它),但为什么sizeof运算符可以应用于指向不完整类型成员的指针? 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. MSVC编译器使用不同大小的指针来指向成员函数作为优化。 This optimization violates the Standard.
此优化违反了标准。 Kudos to Igor Tandetnik mentioning
reinterpret_cast
in a MSDN form post , [expr.reinterpret.cast]p10 感谢Igor Tandetnik在MSDN表格中提到
reinterpret_cast
,[expr.reinterpret.cast] p10
A prvalue of type “pointer to member of
X
of typeT1
” can be explicitly converted to a prvalue of a different type “pointer to member ofY
of typeT2
” ifT1
andT2
are both function types or both object types.如果
T1
和T2
都是函数类型或两种对象类型,则可以将类型为“T1
类型X
的成员的指针”的prvalue显式转换为不同类型的prvalue“指向类型为T2
的Y
的成员的指针”。 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.
将“指向成员函数的指针”类型的prvalue转换为指向成员函数类型的不同指针,并返回其原始类型,从而生成指向成员值的原始指针。
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. 如果设置了
/vmb
开关,则执行MSVC优化。 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 . 对于单继承的情况,优化的指向成员函数的指针只需要一个
void*
-sized存储,参见The Old New Thing:指向成员函数的指针是非常奇怪的动物 。
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). 如果你只是向前声明类型
CL
然后形成一个指向成员的函数,那么优化有望被停用(遗憾的是我找不到任何文档)。 Otherwise, you might get inconsistent sizes before and after the definition of CL
. 否则,在定义
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. 顺便说一下,如果在不指定基础类型的情况下对它们进行前向声明,然后明确定义枚举定义的基础类型,则可以在VS2010中获取枚举的不一致大小。 This works only with language extensions activated.
这仅适用于激活的语言扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.