Unexpected -Wvolatile-register-var warnings when using volatile qualifier for memory‑mapped registers
0 reputation · 03 Feb 2021, 04:16 UTC
0 reputation · 03 Feb 2021, 04:16 UTC
When developing Embedded C code, engineers enable diagnostics such as -Wall -Wextra -Wvolatile-register-var to catch problematic register accesses while using #pragma GCC diagnostic push/pop or #pragma diag_suppress to silence the warning in specific blocks. The goal is to retain useful alerts for genuine issues without exposing notification noise from known‑safe volatile register operations.
However, the C standard leaves the atomicity guarantee of the volatile qualifier implementation‑defined, which creates uncertainty about whether suppressing -Wvolatile-register-var via pragmas might hide non‑atomic accesses that could be reordered or split by the optimizer at different optimization levels.
35275 reputation · 03 Feb 2021, 06:14 UTC
When developers apply the volatile qualifier to a memory‑mapped register, the intent is usually to prevent the compiler from caching the value in a general‑purpose register or eliminating the access. The C standard, however, leaves the atomicity of each volatile access implementation‑defined. This creates a gap between expectation and reality, especially when optimization levels change.
-Wvolatile-register-var fires when the compiler places a volatile variable in a register that could be split across multiple instructions at higher optimization levels.Both GCC and IAR exhibit implementation‑defined volatile handling. Suppressing the warning with #pragma GCC diagnostic push/pop (or the IAR equivalent) only silences the diagnostic; it does not alter the generated code. Consequently, non‑atomic code produced at -O2/-O3 remains hidden behind a suppressed warning.
volatile uint32_t * const REG = (uint32_t * const) 0xE0000000; and reads/writes it.arm-none-eabi-gcc -O0 -S test.c and inspect the produced assembly; look for a single LDR or STR targeting the register address.-O2 and -O3. Check whether the volatile access appears as one instruction or is broken into multiple loads/stores, or is eliminated/hoisted.-Wvolatile-register-var warning flag and observing both the diagnostic output and the generated listing.If you can share the compiler version (e.g., GCC 10.x or IAR EWARM 8.x) and the target CPU family, we can refine the diagnostic check or suggest compiler‑specific pragmas that preserve ordering without suppressing the warning.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.