[英]Why is my static_cast of a pointer failing?
為什么我的指針的 static_cast 失敗了?
int iDog = 456;
int *piDog = &iDog;
long *plDog = static_cast<long*>(piDog); // invalid type conversion
long lDog = static_cast<long>(iDog); // ok
long* plDog = (long*)(piDog); // this is OK too... very weird!! (Dynamic cast... and we aren't allowed to use this one in our coding standards)
該參考表明應該沒問題: https://en.cppreference.com/w/cpp/language/static_cast
Visual Studio C++ 有問題嗎?
long *plDog = static_cast<long*>(piDog); // invalid type conversion
為什么我的指針的 static_cast 失敗了?
因為它的格式不正確。 static_cast 的任何規則都不適用於您正在嘗試的演員表。 正如您在評論中提到的,這是一個無效的轉換。
指向一個 object 類型的指針可能不會被轉換為指向另一個 object 類型的指針的 static,除非它們是指向相關類的指針,或者在轉換到/從指針到 void 時。
該參考表明應該沒問題: https://en.cppreference.com/w/cpp/language/static_cast
該參考表明您嘗試的轉換不正確。
long* plDog = (long*)(piDog); // this is OK too... very weird!!
這是一個格式良好的轉換。 這並不“奇怪”。
顯式轉換(也稱為“轉換表示法”或“C 樣式轉換”)允許進行許多轉換,而 static 轉換則不允許。 這是因為 static 類型轉換具有(至少是類似的)類型安全性,而顯式轉換本質上要求編譯器假裝類型系統不存在。
請注意,通過plDog
間接訪問並訪問 object 將導致未定義的行為。 正如你所看到的,你得到了錯誤是一件好事。
我們不允許在我們的編碼標准中使用這個
這是一個很好的限制。 這將使您的團隊更難通過錯誤地繞過類型系統來編寫錯誤。
Visual Studio C++ 有問題嗎?
不,問題是程序格式不正確。 編譯器正確地通知您錯誤,並且不需要編譯程序。
我建議你問問自己:你為什么想要,或者認為你需要做這樣的演員?
TL;DR:如果您的轉換有效,該語言將不會為指針提供類型安全保證,並且是引入 C++ 樣式轉換而不是堅持使用老式 C 轉換的動機的關鍵部分。
在 C/C++ 標准的語言中, long*
和int*
不是“指針兼容的”。 您不能將long*
隱式轉換為int*
或反之亦然,因此static_cast
不能在一次強制轉換中完成。
其背后的原因是
sizeof(long)
並不總是等於所有平台的sizeof(int)
。 它們是不同的基本類型。 這通常適用於所有不同的 C/C++ 類型,即使它們具有相同的二進制布局。 如果在語言的語法中聲明要通過隱式轉換相關的類型,它們只是“指針兼容的”。
從void*
轉換為指向 object 類型的任何指針時,您可以使用static_cast
,反之亦然。
因此,您可以通過兩種方式做到這一點:
reinterpret_cast<long*>(piDog);
-或者-
static_cast<long*>(static_cast<void*>(piDog));
從風格上講, reinterpret_cast
的使用更加清晰。 在任何一種情況下,強制轉換的有效性都取決於架構,並假設sizeof(int)
== sizeof(long)
以及具有相同的 memory 布局。
IOW 這對於 Windows x86 和 x64 本機是安全的,但可能不適用於其他平台或 CPU。 這是 Windows x64 選擇使用LLP64數據 model 的原因之一,如本博文中所述。
請參閱 cppreference 了解static_cast和reinterpret_cast
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.