Проблема
В низкоуровневом встроенном контенте с чистым металлом я хотел бы создать пустое пространство в памяти внутри структуры 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
для удаления этого предупреждения...