Paul Menzel wrote:
x86_64-linux-gnu-gcc-12 .. -std=gnu11 ..
..
In file included from src/include/cpu/x86/lapic.h:4, from src/cpu/x86/lapic/lapic.c:5: In function 'read32', inlined from 'xapic_read' at src/include/cpu/x86/lapic.h:13:9, inlined from 'lapic_read' at src/include/cpu/x86/lapic.h:80:10, inlined from 'lapicid' at src/include/cpu/x86/lapic.h:138:21, inlined from 'enable_lapic' at src/cpu/x86/lapic/lapic.c:41:3: src/arch/x86/include/arch/mmio.h:20:16: error: array subscript 0 is outside array bounds of 'const volatile void[0]' [-Werror=array-bounds] 20 | return *((volatile uint32_t *)(addr)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
..
I have no idea, if it’s valid or not
gcc-12 is technically correct that accessing element 0 (the first element) in an array with 0 elements is out of bounds.
But in practice it's not a problem for our code, because these are all uint32_t pointers to memory mapped registers (hint: volatile).
So our code is somehow incorrect since these are, in fact, not arrays with 0 elements. The question is why we use them.
One reason can be that older C standards didn't allow arrays to have an unknown size and nobody fixed that using coccinelle when bumping -std=.
Another is that an array with an unknown size must always be the last member in structs, and that there can only ever be one of those and using a 0-sized array can work around that, but IMHO isn't really very pretty.
If possible it would be nicer to use (const?) volatile uint32_t * instead of const volatile void[0], then the casts would also disappear.
Some analysis is required to understand the 0-sized arrays rationale.
Or maybe someone remembers? :)
Kind regards
//Peter