https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104657
--- Comment #5 from Christoph Müllner <christophm30 at gmail dot com> --- Creating hard-wired object references might be a solution, but there is a lot of existing code out there, that would need to be patched (including all the hassle with support for old and new compilers). One example is the bootloader U-Boot, which does the following for ARM ([1]): #define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) Another example is Linux, where read*()/write*() and friends do the following ([2]): # define __iomem void foo_linux(unsigned long v) { void __iomem *p = (void __iomem *)MEM_ADDR; *(volatile unsigned long *)p = v; } FWIW, the __iomem expands in Linux as follows ([3]), if the sources are passed to the semantic parser "sparse" ([4]): # define __iomem __attribute__((noderef, address_space(__iomem))) That's similar to the AVR solution but allows to create user-defined distinct types. [1] https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/include/asm/io.h#L50 [2] https://elixir.bootlin.com/linux/latest/source/include/asm-generic/io.h#L125 [3] https://elixir.bootlin.com/linux/latest/source/include/linux/compiler_types.h#L11 [4] https://git.kernel.org/pub/scm/devel/sparse/sparse.git/tree/Documentation/annotations.rst