Comment éliminer l’avertissement de «qualification de rejet»?

En utilisant les modes GCC et C99, j’ai une fonction déclarée comme:

void func(float *X); 

Lorsque j’appelle la fonction, j’utilise un tableau volatile Y:

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

Lors de la compilation (avec -Wall ), j’obtiens l’avertissement suivant:

 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 *' 

Je peux l’éliminer avec un transtypage de type explicite (float *) , mais cela se répète à de nombreux endroits dans le code.

Existe-t-il un moyen d’éliminer cet avertissement spécifique, avec une option ou un pragma (ou quelque chose d’équivalent)?

Non, vous ne pouvez pas désactiver cet avertissement. Il vous dit que vous violez le système de types. Si vous souhaitez appeler func vous devez soit passer les pointeurs aux données non volatiles, soit modifier la signature de la fonction pour accepter les pointeurs en données volatiles.

La norme permet aux compilateurs de faire tout ce qui leur plaît si un pointeur non qualifié est utilisé pour accéder à un object qualifié volatile . Ceci permet aux plates-formes où certains objects qualifiés volatile peuvent nécessiter des instructions spéciales pour y accéder, par exemple une écriture via volatile uint16_t* peut générer un code équivalent à:

 if ((uintptr_t)ptr >= 0xFFFF0000) __outport16(0xFFFF & (uintptr_t)ptr, value); else (uint16_t*)ptr = value; 

Si un rédacteur de compilateur pense que les compilateurs ne devraient exploiter ces libertés que sur des plates-formes obscures, cela serait coûteux et offrirait des comportements judicieux sur des plates-formes où cela ne coûterait presque rien, et si le code d’appel de l’exemple d’origine sait que aucune entité extérieure n’accédera à Y pendant l’exécution de func ; le code ciblant ce compilateur sera alors en mesure d’obtenir le comportement requirejs sans diagnostic, en transmettant simplement l’adresse de Y à un float* . Malheureusement, les personnes qui maintiennent gcc et clang semblent croire que, lorsque la norme fait référence à des “constructions non portables ou erronées”, elle signifie en réalité “des constructions non portables, c’est-à-dire erronées,” plutôt que des “constructions qui ne sont pas portables à chaque fois. Le fait de placer le pointeur sur float* annulera l’avertissement sur gcc ou clang, mais je ne compterais pas dessus pour que celui-ci produise du code sensible.