-
Notifications
You must be signed in to change notification settings - Fork 172
Description
@faithandbrave さんの commit 1060be9 の bit_cast.md を見て気になったことです。
概要より:
低レイヤーのプログラムでは、同じビットを維持してほかの型に解釈し直すことが必要とされる。その際、
reinterpret_cast
や共用体を使用すると、Strict Aliasing規則に抵触してしまい未定義動作になってしまう。そのような目的にはstd::aligned_storage
とstd::memcpy()
を組み合わせて使用することになるが、それを簡単に使用できるようにしたのが本関数である。
備考にある実装イメージより:
template<typename To, typename From> To bit_cast(const From& from) noexcept { // 実際には、さらに要件チェックが行われる // To型のオブジェクトに直接memcpyするのではなく、アライメント調整した領域にmemcpyして、 // その領域をTo型に再解釈キャストする。 typename std::aligned_storage<sizeof(To), alignof(To)>::type storage; std::memcpy(&storage, &from, sizeof(To)); // memcpyはconstexprではないため、 // コンパイラが特殊な実装をする必要がある return reinterpret_cast<To&>(storage); }
僕の知る限りこの return reinterpret_cast<T&>(storage)
は return reinterpret_cast<To&>(from)
と同じく
実際のオブジェクトと無関係な型でのアクセスを起こすという理由で未定義動作の範囲内にあり、
違うのは memcpy を挟むことで現代のコンパイラで実際に誤動作に至る可能性をほぼ無くせること、
と認識しています。(この効果を一定条件下で規定しちゃおうというのが https://wg21.link/P0593 の目的、と。)
(↑の認識が正しいとして・・・)
現状の記事のままだと、概要の文面と合わせてこの aligned_storage と memcpy を使ったコードが
未定義動作を回避するものと読み取られそうでヤダなーと思ったんですが、だからといって
既存の手法や実装方法に関する記述をざっくり削除するというのも望ましくないものと思います。
というわけで、いったん issue にしてみることにしました。
認識の正誤や記事の改善方針について意見もらえるとうれしいです。