cpointerssyntaxvolatile

Declaring volatile pointer to a pointer which points to non-volatile data


When accessing a hardware register in C/C++, I usually create #defines like this:

#define HW_REGISTER ((volatile uint16_t  *)0xFFFF8A00)

I.e. 0xFFFF8A00 is a pointer to a volatile uint16_t value and this value may be changed from outside so any access to *HW_REGISTER must not be cached.

However what if the value written to the hardware register is actually a pointer? Naively we could just replace uint16_t with uint16_t *:

#define HW_REGISTER ((volatile uint16_t * *)0xFFFF8A00)

but I don't think that's correct. It reads 0xFFFF8A00 is a pointer to a pointer which points to volatile uint16_t data.

The correct way could be:

#define HW_REGISTER ((uint16_t *volatile *)0xFFFF8A00)

i.e. 0xFFFF8A00 is a pointer to a volatile pointer which points to non-volatile uint16_t data.

If I'm correct here, does this mean that if I want to look my #defines consistent, I'm forced to use the swapped syntax, i.e.

#define HW_REGISTER ((uint16_t volatile  *)0xFFFF8A00)

and

#define HW_REGISTER ((uint16_t *volatile *)0xFFFF8A00)

?


Solution

  • It's

    #define HW_REGISTER ( *( uint16_t * volatile * )0xFFFF8A00 )
    

    We read it using the spiral rule:

    It's a pointer to a volatile pointer to a uint16_t.


    If you're unsure, build up the type.

    typedef uint16_t *HW_REGISTER_TYPE;
    
    #define HW_REGISTER_PTR ( ( volatile HW_REGISTER_TYPE * )0xFFFF8A00 )
    
    #define HW_REGISTER ( *HW_REGISTER_PTR )