Зарезервировав немного для различения типа объединения в C ++ - PullRequest
5 голосов
/ 16 июня 2020

В настоящее время у меня есть код, который выглядит следующим образом:

union {
    struct {
        void* buffer;
        uint64_t n : 63;
        uint64_t flag : 1;
    } a;

    struct {
        unsigned char buffer[15];
        unsigned char n : 7;
        unsigned char flag : 1;
    } b;
} data;

Это часть попытки реализации структуры данных, которая выполняет оптимизацию небольшого размера. Хотя он работает на моей машине с компилятором, который я использую, я знаю, что нет никакой гарантии, что два бита флага из каждой структуры фактически окажутся в одном и том же бите. Даже если бы они это сделали, технически все равно было бы неопределенным поведением читать его из структуры, которая не была написана последней. Я хотел бы использовать этот бит, чтобы различать, какой из двух типов в настоящее время хранится.

Есть ли безопасный и переносимый способ добиться того же без увеличения размера объединения? Для нашей цели он не может быть больше 16 байт.

Если нет, можно ли этого добиться, пожертвовав целым байтом (из n в первой структуре и буфера во второй) вместо одного бита ?

...