簡體   English   中英

向上轉換空指針會導致未定義的行為

[英]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是類類型,可以轉換為類型“指向cv B指針”的prvalue,其中BD的基類。 ...空指針值將轉換為目標類型的空指針值。

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是類類型,可以轉換為類型“指向cv B指針”的prvalue,其中BD的基類[...]。 [...]轉換的結果是指向派生類對象的基類子對象的指針。 空指針值將轉換為目標類型的空指針值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM