4

void ポインタに格納されている正確なバイナリを保持しながら、void ポインタを double にキャストするにはどうすればよいですか? これは でできると思っていましreinterpret_cast<double>(voidp)たが、g++ ではできません。void ポインターを整数にキャストできることはわかっているので、試してみreinterpret_cast<double>(reinterpret_cast<long>(voidp))ましたが、明らかにそれも無効です。sizeof(double)sizeof(void*)は両方とも 8 なので、サイズの問題ではありません。これを達成するために私にできることはありますか?

編集: この場合の double は void ポインターによって指されていませんが、/is/ は void ポインターです。ポインター自体には必要なデータが含まれていますが、必要なデータを指していません。

4

4 に答える 4

12

直接メモリの再解釈とは、定義上、左辺値を操作することを意味します。最も簡単なアプローチは、参照型へのキャストを使用して行うことです

double d = reinterpret_cast<double &>(voidp);

他の回答が示唆しているように、ポインターキャストを介して行うこともできますが、完全に不要な多数のオペレーターアプリケーションでプロシージャーを「オーバーロード」します。定義上reinterpret_cast、参照型reinterpret_cast<T &>(v)はポインター バージョンと同等であるため、どちらのアプローチも同等*reinterpret_cast<T *>(&v)です。

ただし、上記のアプローチには型パニングの問題があります。正式には、これを行うことは単に違法です。C++ では、オブジェクトをvoid *オブジェクトとして読み取ることはできません。上記のような任意の型パニングではなく、doubleオブジェクトを s の配列として再解釈するために、C++ にダイレクト メモリ再解釈が存在します。正式な問題を無視して純粋に「実際的な」考慮事項に固執したとしても、値を値としてchar直接再解釈しようとすると、最適化を実行するときに厳密なエイリアス セマンティクスに従うコンパイラで、まったく予期しない無意味な結果が生じる可能性があります。void *double

より良いアイデアはmemcpyvoid *オブジェクトをオブジェクトにするdoubleことです

double d;
assert(sizeof d == sizeof voidp); // <- a static assert would be even better
memcpy(&d, &voidp, sizeof d);

あるいは、C では、その目的で共用体を使用できるようになりました。C++ に正式な許可が与えられたかどうかはまだわかりませんが、通常は実際に機能します。

于 2013-10-15T17:53:57.993 に答える