Pourquoi gcc -Wformat ne met-il pas en garde sur printf% d sur un entier non signé?

Le programme suivant a un comportement indéfini:

#include  int main(void) { unsigned int x = -100; // This is fine, becomes UINT_MAX - 100 printf("%d\n", x); // This is undefined behavior. return 0; } 

C99 7.19.6.1p8 déclare que% d attend un argument int.

C99 7.19.6.1p9 déclare “Si l’un des arguments n’est pas du type correct pour la spécification de conversion correspondante, le comportement est indéfini .”

Cependant, gcc -Wformat (qui est inclus avec -Wall ) ne se plaindra pas du programme ci-dessus, pourquoi? Est-ce un bug ou une omission délibérée?

De la page de manuel de gcc:

 -Wformat 

Vérifiez les appels à "printf" et "scanf" , etc., pour vous assurer que les arguments fournis ont des types appropriés à la chaîne de format spécifiée et que les conversions spécifiées dans la chaîne de format ont un sens.

Ma meilleure hypothèse est que l’avertissement est ignoré parce que l’UB est invoqué sans doute par la valeur et pas simplement par le type. va_arg autorise la non-concordance de la signature tant que la valeur est représentable dans les types signé et non signé. Cependant, printf et amis ne sont pas spécifiés en termes de va_arg et la norme indique que toute incompatibilité de type entraîne UB, mais il s’agit probablement d’un bogue de la norme. Sinon, printf("%x",1); invoquer UB. Voir ma question sur le sujet:

Printf (“% x”, 1) appelle-t-il un comportement non défini?