[英]Does upcasting a null pointer lead to undefined behavior
我想知道以下代碼是否導致未定義的行為:
#include <cstddef>
#include <cstdio>
struct IA {
virtual ~IA() {}
int a = 0;
};
struct IB {
virtual ~IB() {}
int b = 0;
};
struct C: IA, IB {};
int main() {
C* pc = nullptr;
IB* pib = pc;
std::printf("%p %p", (void*)pc, (void*)pib);
}
向上轉換空指針是明確定義的,以便為您提供另一個空指針:
4.10p3:
類型為“指向cv
D
指針”的prvalue,其中D
是類類型,可以轉換為類型“指向cvB
指針”的prvalue,其中B
是D
的基類。 ...空指針值將轉換為目標類型的空指針值。
Stroustrup在1989年的多重繼承文件[PDF]第4.5節中討論了這個案例:
解決方案是詳細說明轉換(強制轉換)操作以測試指針值0 [...]
增加的復雜性和運行時開銷是測試和增量。
該實現顯式檢查空值,並確保轉換的結果仍為空值。 這在C ++ 98中是正確的,並且在C ++ 11和nullptr
沒有改變。
這在多個基類的情況下尤其重要,其中從派生類到其中一個基類的強制轉換可能需要更改指針的實際值。
在您的示例中,內存中C
的布局將首先包含IA
的字節,然后是IB
的字節。 投射到IA
是繁瑣,作為指針的開頭C
也將指向開頭IA
的一部分C
。 另一方面,轉換為IB
,需要將C
指針移動IA
的大小。 在nullptr情況下執行此移位將導致在強制轉換后的非空指針,因此對空值進行特殊處理。
正如aschepler所指出的 ,標准中的相關部分是[conv.ptr]§4.10:
類型為“指向cv
D
指針”的prvalue,其中D
是類類型,可以轉換為類型“指向cvB
指針”的prvalue,其中B
是D
的基類[...]。 [...]轉換的結果是指向派生類對象的基類子對象的指針。 空指針值將轉換為目標類型的空指針值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.