Проблема
В низкоуровневом встроенном контексте « голого металла» я хотел бы создать пустое пространство в памяти внутри структуры C ++ без какого-либо имени, чтобы запретить пользователю доступ к такой области памяти.
Прямо сейчас я добился этого, поместив уродливое uint32_t :96;
битовое поле, которое удобно заменит три слова, но вызовет предупреждение от GCC (битовое поле слишком велико, чтобы поместиться в uint32_t), что вполне законно.
Хотя он работает нормально, он не очень чистый, если вы хотите распространить библиотеку с несколькими сотнями этих предупреждений ...
Как мне это сделать правильно?
Почему вообще возникает проблема?
Проект, над которым я работаю, состоит из определения структуры памяти различных периферийных устройств всей линейки микроконтроллеров (STMicroelectronics STM32). Для этого результатом является класс, который содержит объединение нескольких структур, которые определяют все регистры, в зависимости от целевого микроконтроллера.
Вот один простой пример довольно простого периферийного устройства: универсальный ввод / вывод (GPIO)
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
Где all GPIO_MAPx_YYY
- макрос, определяемый либо как, либо как uint32_t :32
тип регистра (выделенная структура).
Здесь вы видите, uint32_t :192;
что работает хорошо, но вызывает предупреждение.
Что я рассмотрел до сих пор:
Я мог бы заменить его несколькими uint32_t :32;
(здесь 6), но у меня есть несколько крайних случаев, когда у меня есть uint32_t :1344;
(42) (среди других). Так что я бы не стал добавлять около сотни строк поверх 8k других, даже если генерация структуры написана по сценарию.
Точное предупреждающее сообщение выглядит примерно так:
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(Мне просто нравится, насколько это сомнительно).
Я бы предпочел не решать эту проблему, просто удаляя предупреждение, но используя
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
может быть решение ... если найду TheRightFlag
. Однако, как указано в этой теме , gcc/cp/class.c
с этой печальной частью кода:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
Это говорит нам, что нет -Wxxx
флага для удаления этого предупреждения ...
char unused[12];
и так далее?