This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Volatile struct members

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

Parents
  • 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/

Reply
  • 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/

Children
  • 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