簡體   English   中英

reinterpret_cast 會導致嚴格的別名沖突嗎?

[英]Does reinterpret_cast cause a strict aliasing violation?

為什么它甚至存在? 在什么情況下它不會導致嚴格的混疊違規,在哪些情況下會導致?

我的意思是,如果您在兩個不兼容的類型之間進行轉換,並且該轉換的結果是唯一指向它在整個程序中使用的 memory 的指針,那么在假設沒有其他別名引用 memory 的情況下使用它是否安全? 然后將其轉換回其原始類型並假設存儲它的變量是程序上該 memory 位置的唯一別名,是否安全? 這就是我要問的。

我當然是指閱讀和寫作。

reinterpret_cast 會導致嚴格的別名沖突嗎?

不是單獨的,不。 但它的濫用可能導致這種違規行為。

使用 reinterpret cast 不是一個好主意,除非你知道你需要它(很少見),知道沒有令人滿意的替代品(很少見),並且知道它不會導致未定義的行為。

為什么它甚至存在?

顧名思義,允許重新解釋類型。 C++ 中的用例很少見,既不適合初學者,也不適合中級程序員。

高級程序員可能會遇到它有用的一些情況:

  • 序列化
  • C 接口使用重新解釋作為多態性的一種形式。

在什么情況下它不會導致嚴格的混疊違規,在哪些情況下會導致?

演員表本身不會導致任何違規行為。

只有當您轉換為另一種類型的指針(或引用),然后通過該指針間接訪問 object 時,才會發生嚴格的別名違規。 因此,如果您不重新解釋轉換指針(或引用),或者您不訪問指向的 object,那么您就不會對 object 的類型進行別名,因此不能違反嚴格的別名規則。

因此,有趣的是使用另一種(別名)類型訪問 object 是否定義明確。 這是來自cppreference的列表:

  • AliasedType 和 DynamicType 是類似的。
  • AliasedType 是 DynamicType 的(可能是 cv 限定的)有符號或無符號變體。
  • AliasedType 是 std::byte (C++17 起)、char 或 unsigned char:這允許將任何 object 的 object 表示檢查為字節數組。

此列表中缺少的是:

  • DynamicType 的指向 object 可與 AliasedType 的另一個 object 指針互轉換。

如果你在兩個不兼容的類型之間轉換,(...),使用它是否安全

取決於您所說的“使用”是什么意思。 如果您的意思是通過重新解釋的指針間接並通過“不兼容”類型訪問 object,那么一般來說這不安全。

並且該轉換的結果是唯一指向它在整個程序中使用的 memory 的指針

這是無關緊要的。 在大多數情況下,編譯器幾乎不可能證明這是真的。

那么將其轉換回其原始類型並假設存儲它的變量使用它是否安全

假設轉換到另一種類型的格式一開始就很好,那么轉換回原始類型總是安全的。

首先,使用reinterpret_cast本身不會觸發未定義的行為,但使用它的結果很可能會 - 所以我們將繼續考慮reinterpret_cast本身,而不是它的用法。 還必須注意,只要兩種類型的大小相同,就定義了強制轉換和返回,但是很少有人會為此使用reinterpret_cast - 在大多數情況下,人們會使用void*作為中間和static_cast可以。

嚴格的別名規則總是有點爭議。 它使一些編譯器優化成為可能,但它也抑制了許多實體序列化技術,隨着時間的推移,這些技術被證明非常有價值。

使用實體序列化的情況非常合理,並且大量系統使用reinterpret_cast重構數據。 誠然,這在技術上會調用未定義的行為,但這是人們通常願意做出的權衡。

隨着 C++20 中bit_cast的引入,我希望備受爭議的reinterpret_cast能看到黃昏。

為什么它甚至存在?

  1. 因為基本上任何處理硬件都可以做到。
  2. 因為你可以在 C 和 C 開發的 C++ 中做到這一點。
  3. 因為它在難以或可能無法更換的情況下很有用。
  4. ...如果你想替換它,它可能是幾乎相同的東西,例如你寫一個成員並閱讀另一個成員的聯合。

暫無
暫無

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

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