The task -std=c++14 to change the semantics of the volatile expression other than (void) and introduce an explicit unconditional warning for it, and the encoder in ST tries to make it βtriple sureβ that the register is read.
UNUSED() macro UNUSED()
#define UNUSED(x) ((void)(x))
and __IO is defined as
#define __IO volatile
Then the expansion __HAL_RCC_GPIOB_CLK_ENABLE() would be
do { volatile uint32_t tmpreg; RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; tmpreg = RCC->AHB2ENR & RCC_AHB2ENR_GPIOBEN; ((void)(tmpreg)); } while(0)
Register latency and return are recommended by various STM32 errors saying
To control peripheral read / write registers, consider the delay between the RCC peripheral clock on and the effective peripheral on.
[...]
insert a fictitious read operation from the corresponding register immediately after allowing the peripheral clock.
Since all peripheral registers, of course, are declared volatile , a simple expression containing only this register will force a read with the necessary wait states through the same peripheral bus, so this will be enough:
do { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; RCC->AHB2ENR; } while(0)
the rest is apparently a reworked workaround for some error compilers, but I can still see that one of them is so broken that an expression with a mutable type will be optimized.
However, there is this extreme case where the volatile variable is changed to (void) , where the semantics seem to have changed in C ++ 14.
Take this simple example
void x() { volatile int t; t=1; ((void)(t)); }
Arm gcc 7.2.1, called with -O3 -mcpu=cortex-m4 -mthumb -Wall -x c++ -std=c++11 , will compile it
x(): sub sp, sp, #8 movs r3, #1 str r3, [sp, #4] ldr r3, [sp, #4] add sp, sp, #8 bx lr
the same code compiled with -std=c++14 ,
x(): sub sp, sp, #8 movs r3, #1 str r3, [sp, #4] add sp, sp, #8 bx lr
... and warning:
<source>: In function 'void x()': <source>:5:13: warning: conversion to void will not access object of type 'volatile int' ((void)(t)); ~^~
Also note the missing ldr command in the second case. This variable is not available after writing from C ++ 14.
My initial question was to find out the solution, leaving the underlying ST driver intact. One possible solution would be to use direct access to the register without going through a convenient macro library.
I suggest going ahead and avoiding the library; IMHO HAL is best seen as a collection of examples or implementation suggestions.
* I could not find a way to disable it. This does not mean that they are not.