たとえば、ポインターとbool
. 簡単にするために、例ではポインターが使用されますが、ポインターの型は、 1 より大きいint
ものを指している限り関係ありません。size()
クラスをデータ メンバーで定義すると、クラス{ bool , int *}
のサイズがポインターのサイズの 2 倍になり、多くの無駄なスペースが発生します。
char
ポインターが(または の他のデータ)を指していない場合、size(1)
おそらく下位ビットは常に 0 になります。クラスは{int *}
便宜上 または で定義できます。union { int *, uintptr_t }
これbool
は、論理値に従ってポインターの下位ビットを設定/クリアし、ポインターbool
を使用する必要があるときにビットをクリアすることによって実装されます。
定義された方法:
struct myData
{
int * ptr;
bool flag;
};
myData x;
// initialize
x.ptr = new int;
x.flag = false;
// set flag true
x.flag = true;
// set flag false
x.flag = false;
// use ptr
*(x.ptr)=7;
// change ptr
x = y; // y is another int *
そして提案された方法:
union tiny
{
int * ptr;
uintptr_t flag;
};
tiny x;
// initialize
x.ptr = new int;
// set flag true
x.flag |= 1;
// set flag false
x.flag &= ~1;
// use ptr
tiny clean=x; // note that clean will likely be optimized out
clean.flag &= ~1; // back to original value as assigned to ptr
*(clean.ptr)=7;
// change ptr
bool flag=x.flag;
x.ptr = y; // y is another int *
x.flag |= flag;
これは未定義の動作のようですが、これはどの程度移植性がありますか?