Раздел 9.6/3 в С++ 11 необычайно ясен: "Неконстантная ссылка не должна привязываться к битовому полю". Какова мотивация этого запрета?
Я понимаю, что невозможно напрямую привязать ссылку к битовому полю. Но если я объявлю что-то вроде этого,
struct IPv4Header {
std::uint32_t version:4, // assumes the IPv4 Wikipedia entry is correct
IHL:4,
DSCP:6,
ECN:2,
totalLength:16;
};
Почему я не могу сказать это?
IPv4Header h;
auto& ecn = h.ECN;
Я ожидаю, что базовый код будет фактически привязан ко всему std::uint32_t
, который содержит интересующие меня биты, и я ожидаю, что операции чтения и записи будут генерировать код для соответствующей маскировки. Результат может быть большим и медленным, но мне кажется, что он должен работать. Это было бы согласуется с тем, как стандарт говорит, что ссылки на const
битовые поля работают (опять же из 9.6/3):
Если инициализатор для ссылки типа const T & является значением l, которое ссылается на бит-поле, ссылка привязана к временному инициализированному удерживать значение битового поля; ссылка не привязана непосредственно к битовому полю.
Это говорит о том, что проблема с записью в битполы - проблема, но я не понимаю, что это такое. Я рассмотрел возможность того, что необходимая маскировка может вводить расы в многопоточном коде, но на 1.7/3 смежные битовые поля ненулевой ширины считаются одним объектом для целей многопоточности. В приведенном выше примере все битовые поля в объекте IPv4Header
будут считаться одним объектом, поэтому многопоточный код, пытающийся модифицировать поле при чтении других полей, по определению уже будет искушенным.
Мне явно чего-то не хватает. Что это?