Если есть, например, класс, для которого требуется указатель, и bool
. Для простоты в примерах будет использоваться указатель int
, но тип указателя не имеет значения, если он указывает на то, что size()
больше 1.
Определение класса с членами { bool , int *}
приведет к тому, что класс имеет размер, который вдвое больше размера указателя и много потерянного пространства
Если указатель не указывает на char
(или другие данные size(1)
), то предположительно младший бит всегда будет равен нулю. Класс может быть определен с помощью {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;
Это похоже на поведение undefined, но насколько переносимым является это?