To fk0: Известо, что ключевое слово volatile было частично объявлено deprecated начиная с С++20. При попытке сборки кода с ключом -std=c++20:
// Где-нибудь в заголовочниках с описанием регистров от производителя
#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
#define GPIOA (GPIO_BASE + 0x00000000U)
#define GPIO_CTL0(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register 0 */
// ... Другие регистры аналогично
// В моем коде
inline static void Init() noexcept(true) {
constexpr std::uint32_t regs{static_cast<std::uint32_t>(kPort)};
if constexpr (kPin < 8)
{
GPIO_CTL0(regs) &= kCtl0ClearMask;
if constexpr (kCtl0Mask != 0) GPIO_CTL0(regs) |= kCtl0Mask;
}
else
{
GPIO_CTL1(regs) &= kCtl1ClearMask;
if constexpr (kCtl1Mask != 0) GPIO_CTL1(regs) |= kCtl1Mask;
}
GPIO_BOP(regs) = kBopInitMask;
}
Можно получить следующий результат:
warning: compound assignment with ‘volatile’-qualified left operand is deprecated [-Wvolatile]
Вопрос в том, как правильно работать с регистрами периферии в контексте С++20? Отсутствие volatile может привести к проблемам при включенной оптимизации. Я сейчас штудирую материалы по этой теме, в том числе proposal, но спросить таки быстрее.