Перейдите к жирной части для существенного вопроса, остальное только фон.
По причинам, по которым я предпочитаю не вдаваться, я пишу генератор кода, который генерирует структуры C ++ в (очень) среде до C ++ 14. Генератор должен создавать битовые поля; ему также необходим как можно более жесткий контроль за поведением сгенерированных полей, насколько это возможно. Мне нужно контролировать как размер базовой единицы выделения, так и то, как обрабатываются подписанные значения. Я не буду вдаваться в то, почему я нахожусь в таком дурацком поручении, которое так явно идет вразрез с поведением, определяемым реализацией, но в этом есть зарплата, и люди отвергли все правильные способы сделать то, что нужно сделать. кто организует зарплату.
Так что я застрял, создавая такие вещи, как:
int32_t x : 11;
потому что мне нужно убедить компилятор, что это поле (и другие смежные поля с таким же базовым типом) находятся в 32-битном слове. Генерация int
для базового типа не возможна, потому что int не имеет фиксированного размера, и все пойдет не так, как только кто-то выпустит компилятор, в котором int имеет ширину 64 бита, или мы вернемся к тому, где сейчас 16.
В пре-C ++ 14 int x: 11
может быть или не быть полем без знака, и вы добавляете явное signed
или unsigned
, чтобы получить то, что вам нужно. Я обеспокоен тем, что int32_t и друзья будут иметь одинаковую двусмысленность (почему бы и нет?), Но компиляторы заткнули рот signed int32_t
.
Есть ли в стандарте C ++ какие-либо слова о том, накладывает ли типы intxx_t свою подпись на битовые поля? Если нет, есть ли гарантия, что что-то вроде
typedef signed int I32;
...
I32 x : 11;
...
assert(sizeof(I32)==4); //when this breaks, you won't have fun
будет переносить подписанный индикатор в битовое поле?
Пожалуйста, обратите внимание, что любое предложение, которое начинается с "просто сгенерировать функцию для ...", является указанием со стола. Эти сгенерированные заголовки будут включены в код, который выполняет такие действия, как s-> x = 17; и мне было хорошо объяснено, что я не должен предлагать изменить все это на s->set_x(17)
даже еще раз. Даже при том, что я мог бы тривиально сгенерировать функцию set_x, чтобы точно и безопасно делать то, что мне нужно, без какого-либо поведения, определенного для реализации. Кроме того, я очень хорошо осведомлён о капризах битовых полей и слева направо и справа налево и наизнанку и обо всём остальном, с чем сталкиваются компиляторы, и нескольких других причинах, по которым это глупое поручение. И я не могу просто «пробовать вещи», потому что это должно работать на компиляторах, которых у меня нет, поэтому я карабкаюсь за гарантиями в стандарте.
Примечание: я не могу реализовать ни одно решение, которое не позволяет существующему коду просто приводить указатель на буфер байтов к указателю на сгенерированную структуру, а затем использовать их указатель для доступа к полям для чтения и записи , Существующий код полностью посвящен s-> x и должен работать без изменений. Это исключает любое решение, включающее конструктор в сгенерированном коде.