0
/* low level macros for accessing memory mapped hardware registers */
#define REG64(addr) ((volatile uint64_t *)(uintptr_t)(addr))
#define REG32(addr) ((volatile uint32_t *)(uintptr_t)(addr))
#define REG16(addr) ((volatile uint16_t *)(uintptr_t)(addr))
#define REG8(addr) ((volatile uint8_t *)(uintptr_t)(addr))

I understand the cast to uint64_t* but why volatile? Which optimization is being prevented here?

Also, why cast to uintptr_t = typedef unsigned long uintptr_t before casting to uintXX_t?

Rafaelo
  • 33
  • 1
  • 15

1 Answers1

1

volatile means that they intend that the value of the register may change through actions outside of the standard part of the program . E.g. reading the register now and reading it again later may give a different value even if your code didn't set a value.

The behaviour of cast from integer to pointer is implementation-defined which means the compiler documentation must document what happens in the case of the cast being present, and in the case of the cast being omitted.

It might turn out to be defensive coding e.g. the coder wasn't really sure but felt that converting to an integer of the same size as the pointer first (which is well-defined) was going to be more reliable than omitting the cast.

M.M
  • 138,810
  • 21
  • 208
  • 365