Питання
У контексті низькорівневого вбудованого металу , я хотів би створити порожній простір в пам'яті, в структурі 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) (серед інших). Тому я волів би не додавати близько ста рядків поверх 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
прапора для видалення цього попередження ...
uint32_t :192;
.
:42*32
замість цього ви можете писати:1344
char unused[12];
і так далі?