[英]Does reinterpret_cast cause a strict aliasing violation?
為什么它甚至存在? 在什么情況下它不會導致嚴格的混疊違規,在哪些情況下會導致?
我的意思是,如果您在兩個不兼容的類型之間進行轉換,並且該轉換的結果是唯一指向它在整個程序中使用的 memory 的指針,那么在假設沒有其他別名引用 memory 的情況下使用它是否安全? 然后將其轉換回其原始類型並假設存儲它的變量是程序上該 memory 位置的唯一別名,是否安全? 這就是我要問的。
我當然是指閱讀和寫作。
reinterpret_cast 會導致嚴格的別名沖突嗎?
不是單獨的,不。 但它的濫用可能導致這種違規行為。
使用 reinterpret cast 不是一個好主意,除非你知道你需要它(很少見),知道沒有令人滿意的替代品(很少見),並且知道它不會導致未定義的行為。
為什么它甚至存在?
顧名思義,允許重新解釋類型。 C++ 中的用例很少見,既不適合初學者,也不適合中級程序員。
高級程序員可能會遇到它有用的一些情況:
在什么情況下它不會導致嚴格的混疊違規,在哪些情況下會導致?
演員表本身不會導致任何違規行為。
只有當您轉換為另一種類型的指針(或引用),然后通過該指針間接訪問 object 時,才會發生嚴格的別名違規。 因此,如果您不重新解釋轉換指針(或引用),或者您不訪問指向的 object,那么您就不會對 object 的類型進行別名,因此不能違反嚴格的別名規則。
因此,有趣的是使用另一種(別名)類型訪問 object 是否定義明確。 這是來自cppreference的列表:
此列表中缺少的是:
如果你在兩個不兼容的類型之間轉換,(...),使用它是否安全
取決於您所說的“使用”是什么意思。 如果您的意思是通過重新解釋的指針間接並通過“不兼容”類型訪問 object,那么一般來說這不安全。
並且該轉換的結果是唯一指向它在整個程序中使用的 memory 的指針
這是無關緊要的。 在大多數情況下,編譯器幾乎不可能證明這是真的。
那么將其轉換回其原始類型並假設存儲它的變量使用它是否安全
假設轉換到另一種類型的格式一開始就很好,那么轉換回原始類型總是安全的。
首先,使用reinterpret_cast
本身不會觸發未定義的行為,但使用它的結果很可能會 - 所以我們將繼續考慮reinterpret_cast
本身,而不是它的用法。 還必須注意,只要兩種類型的大小相同,就定義了強制轉換和返回,但是很少有人會為此使用reinterpret_cast
- 在大多數情況下,人們會使用void*
作為中間和static_cast
可以。
嚴格的別名規則總是有點爭議。 它使一些編譯器優化成為可能,但它也抑制了許多實體序列化技術,隨着時間的推移,這些技術被證明非常有價值。
使用實體序列化的情況非常合理,並且大量系統使用reinterpret_cast
來重構數據。 誠然,這在技術上會調用未定義的行為,但這是人們通常願意做出的權衡。
隨着 C++20 中bit_cast
的引入,我希望備受爭議的reinterpret_cast
能看到黃昏。
為什么它甚至存在?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.