Hi,
I would like to prevent structure members optimization. I used volatile keyword:
typedef volatile struct { volatile ... volatile uint32_t discard; volatile ... } regs_t;
I declared a member in another non-volatile struct:
typedef struct { ... volatile regs_t *regs; ... } peripheral_t;
I used an "empty" expression to just clear flags in register (the memory read access must be performed):
peripheral_t p; p.regs = 0x12345678; /* init to register block starting address */ p.regs->discard; /* gets optimized out when opt. is on */
The "empty" expression gets optimized out although I thought (hoped) I prevented it via the volatile keywords. - What is the right place to put the volatile? - Does the whole struct have to be volatile? - Does it make sense to define volatile type? (typedef volatile struct...)
Thanks for tips/explanations.
Regards Pavel
According to the ARM ABI, volatile is applied recursively to all members of a struct.
I am not sure what the C standard says about (non-volatile) composite data types containing (non-volatile) pointers to volatile types.
It could well be the case that the compiler behavior is perfectly legal. Try qualifying peripheral_t as volatile just to see if that changes anything.
I recommend to manage peripherals using structures placed via at-attribute or the scatter loading file (linker script). Some also use integer literals cast to pointers to structs.
@Andy > you probably should be writing in assembler
But C is "[...](the PDP-11 assembler that thinks it's a language) and C++ (the PDP-11 assembler that thinks it's an object system)[...]" (Jamie Zawinski)
Regards Marcus http://www.doulos.com/arm/
Me says: > I am not sure what the C standard says about > (non-volatile) composite data types containing > (non-volatile) pointers to volatile types.
I think I found it in 6.7.3 §5: If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.
-- Marcus