cancel
Showing results for 
Search instead for 
Did you mean: 

const volatile objects are not stored in .rodata

CTapp.1
Associate III

I often use const data tables that may be changed by a configuration process at runtime. Depending on how these tables are used, it is sometimes necessary to make them volatile so that accesses to the values are not replaced by the use of inline constant values during optimisation.

However, these tables are unexpectedly placed in the .data RAM section - which is not the case when they are simply const, when they are, as expected, placed in the .rodata FLASH section.

static const          T table1[];   // This is placed in .rodata
static const volatile T table2[];   // This is placed in .data

After a bit of research, I found that this behaviour does not agree with that in Clang/LLVM. See:

  1. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25521
  2. https://github.com/llvm/llvm-project/issues/56468

A patch was added to GCC to bring its behaviour in line with that of Clang. However, it appears as if the current version of GCC used by the STM32CubeIDE (V.1.15.1) is too old for this to have been included.

It is easy enough to use an attribute as a work-around:

static const volatile T table3[] __attribute__((section( ".rodata" )));   // This is placed in .rodata

but I thought it was worth mentioning here in case anyone else runs into this and to warn of a potential change in behaviour when the supported version of GCC changes.

4 REPLIES 4
Bob S
Principal

"const" and "volatile" are non-compatible attributes.  One says "this data will never change" and the other says "this data may change at any time without warning".  If the data can change, it is by definition not constant.  I could understand if the actual data were declared non-const but then it was accessed by pointers/references that WERE const.

Sorry, but that is not the case and it would have been made a constrain violation within the language standard if it were.

const indicates that it is not modifiable by the program, where as volatile indicates that the value may change by a mechanism that is not visible to the program (this will typically be a hardware interaction).

It is common for hardware registers to have const volatile qualification, and it is necessary to ensure that constructs such as

while ( hardware_register != someValue )
{
  // Wait for it to change
}

are not optimised to give a single fetch from hardware_register.

"const volatile" may be valid as you've described (does make sense for things like read-only status registers to prevent code from writing to them).  That said, "volatile" is sufficient to prevent the "single fetch" issue you mentioned.  At least with my experience with GCC.

Sure, but it needs the const to stop the object being placed in RAM.