выпуск
В контексте низкоуровневого встроенного чистого металла я хотел бы создать пустое пространство в памяти внутри структуры 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;
};
};
Где все GPIO_MAPx_YYY
- это макрос, определенный как uint32_t :32
или тип регистра (выделенная структура).
Здесь вы видите uint32_t :192;
, который хорошо работает, но выдает предупреждение.
То, что я до сих пор считал:
Я мог бы заменить его на несколько uint32_t :32;
(6 здесь), но у меня есть несколько крайних случаев, когда у меня есть uint32_t :1344;
(42) (среди прочих). Поэтому я бы предпочел не добавлять около ста строк поверх остальных 8 тыс., Хотя генерация структуры написана по сценарию.
Точное предупреждение выглядит примерно так:
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
...