[英]pointer to member function of incomplete type
我不明白為什么為類添加前向聲明會將其指針的大小更改為成員類型
#include <iostream>
using namespace std;
int main()
{
//struct CL;
//cout<<sizeof(int (CL::*)())<<endl;
struct CL{};
cout<<sizeof(int (CL::*)())<<endl;
}
輸出VS2013:
4
但是如果我取消注釋main()中的前兩行,那么輸出是不同的:
16
16
因此,在struct CL的定義之前只添加一個前向聲明只會增加指向CL成員的指針的大小。 為什么? 我知道成員函數指針的大小取決於類型的結構(例如,虛函數和基類可能會增加它),但為什么sizeof運算符可以應用於指向不完整類型成員的指針? 還是不行? 我沒有在標准中找到它
MSVC編譯器使用不同大小的指針來指向成員函數作為優化。 此優化違反了標准。 感謝Igor Tandetnik在MSDN表格中提到reinterpret_cast
,[expr.reinterpret.cast] p10
如果
T1
和T2
都是函數類型或兩種對象類型,則可以將類型為“T1
類型X
的成員的指針”的prvalue顯式轉換為不同類型的prvalue“指向類型為T2
的Y
的成員的指針”。 空成員指針值將轉換為目標類型的空成員指針值。 除以下情況外,此轉換的結果未指定:
- 將“指向成員函數的指針”類型的prvalue轉換為指向成員函數類型的不同指針,並返回其原始類型,從而生成指向成員值的原始指針。
因此有一個往返保證,這有效地迫使符合實現對所有指向成員函數類型的指針使用相同的大小。
如果設置了/vmb
開關,則執行MSVC優化。 對於單繼承的情況,優化的指向成員函數的指針只需要一個void*
-sized存儲,參見The Old New Thing:指向成員函數的指針是非常奇怪的動物 。
如果你只是向前聲明類型CL
然后形成一個指向成員的函數,那么優化有望被停用(遺憾的是我找不到任何文檔)。 否則,在定義CL
之前和之后,您可能會得到不一致的大小。
順便說一下,如果在不指定基礎類型的情況下對它們進行前向聲明,然后明確定義枚舉定義的基礎類型,則可以在VS2010中獲取枚舉的不一致大小。 這僅適用於激活的語言擴展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.