あなたが提案した結合方法は、ほとんどの人が取る通常のルートです。ただし、C/C++ では、最後に記述されたものとは異なるメンバーを共用体から読み取ることは、技術的に未定義の動作です。それにもかかわらず、ほとんどすべてのコンパイラで十分にサポートされています。
Jon Skeet が提案したように、ポインターのキャストは悪い考えです。これは、C の厳密なエイリアシングunsigned long *
ルールに違反します。積極的な最適化コンパイラは、型のポインターを想定し、float *
互いにエイリアスを作成しないため、これに対して誤ったコードを生成します。
標準への準拠 (つまり、未定義の動作を呼び出さない) の観点から最も正しい方法は、 を介してキャストすることchar*
です。これは、厳密なエイリアシング規則により、char*
ポインターが他の型のポインターにエイリアスすることが許可されているためです。
unsigned long ul = 0x40A00000;
float f;
char *pul = (char *)&ul; // ok, char* can alias any type
char *pf = (char *)&f; // ok, char* can alias any type
memcpy(pf, pul, sizeof(float));
正直なところ、私はユニオン方式を使用します。上記の cellperformance.com リンクから:
これは非常に一般的なイディオムであり、すべての主要なコンパイラで十分にサポートされています。実際問題として、任意の順序で組合の任意のメンバーに対して読み取りと書き込みを行うことは、許容される慣行です。