Using GCC and C99 mode, I have a function declared as:
void func(float *X);
When I call the function, I use a volatile array Y:
<
The Standard allows compilers to do anything they like if a non-qualified pointer is used to access a volatile
-qualified object. This allows for platforms where some volatile
-qualified objects may require special instructions to access them, where e.g. a write via volatile uint16_t*
might do generate code equivalent to:
if ((uintptr_t)ptr >= 0xFFFF0000)
__outport16(0xFFFF & (uintptr_t)ptr, value);
else
(uint16_t*)ptr = value;
If a compiler writer takes the attitude that compilers should only exploit such freedoms on obscure platforms were doing otherwise would be expensive, and should provide sensible behaviors on platforms where doing so would cost almost nothing, and if the calling code in the original example knows that no outside entities will access Y
during the execution of func
, then code targeting that compiler will be able to achieve the required behavior without a diagnostic merely by casting Y's address to a float*
. Unfortunately, the people maintaining gcc and clang seem to believe that when the Standard refers to "non-portable or erroneous constructs", it really means "non-portable, i.e. erroneous, constructs" rather than "constructs which are not portable to every single conforming machine in the Universe, and would be erroneous if such portability were intended. Casting the pointer to float*
will silence the warning on gcc or clang, but I wouldn't count on it causing them to yield sensible code.
No, you can't turn that warning off. It's telling you you're violating the type system. If you want to call func
you either need to pass it pointers to non-volatile data or change the function signature to accept pointers to volatile data.