Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to eliminate the "discard qualifier" warning?

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:

volatile float Y[2];
int main()
{
    func(Y);
    return 0;
}

When compiling (with -Wall), I get the following warning:

warning: passing argument 1 of ‘func’ discards qualifiers from pointer target type
blah.c:4: note: expected ‘float *’ but argument is of type ‘volatile float *’

I can eliminate it with an explicit (float *) type cast, but this repeats in many places in the code.

Is there a way to eliminate this specific warning, with an option or a pragma (or something equivalent)?

like image 282
ysap Avatar asked Aug 28 '12 16:08

ysap


2 Answers

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.

like image 157
Jonathan Wakely Avatar answered Nov 15 '22 02:11

Jonathan Wakely


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.

like image 1
supercat Avatar answered Nov 15 '22 02:11

supercat