-Werror = format: comment le compilateur peut-il savoir

J’ai écrit ce code intentionnellement faux

printf("%d %d", 1); 

comstackr avec g++ et -Werror=format .

Le compilateur donne cet avertissement très impressionnant:

 error: format '%d' expects a matching 'int' argument [-Werror=format] 

Autant que je sache, il est impossible pour le compilateur de dire que le code est erroné, car la chaîne de formatage n’est pas analysée avant l’exécution.

Ma question: le compilateur a-t-il une fonctionnalité spéciale qui active les fonctions printf et similaires de la libc, ou s’agit-il d’une fonctionnalité que je pourrais utiliser pour mes propres fonctions? Des littéraux de chaîne?

Autant que je sache, il est impossible pour le compilateur de dire que le code est erroné, car la chaîne de formatage n’est pas analysée avant l’exécution.

Tant que la chaîne de format est un littéral de chaîne, elle peut être analysée au moment de la compilation. Si ce n’est pas le cas (ce qui est généralement une mauvaise idée), vous pouvez obtenir un avertissement à ce sujet auprès de -Wformat-security .

le compilateur a-t-il une fonctionnalité spéciale qui active les fonctions printf et libc similaires?

Oui.

ou est-ce une fonctionnalité que je pourrais utiliser pour mes propres fonctions?

Oui, tant que vous utilisez le même style de chaîne de format que printf (ou diverses autres fonctions standard telles que scanf ou strftime ).

 void my_printf(Something, char const * format, SomethingElse, ...) __atsortingbute__ ((format (printf,2,4))); 

pour indiquer que le deuxième argument est une printf format printf -style et que les valeurs à formater commencent par le quasortingème. Voir http://gcc.gnu.org/onlinedocs/gcc/Function-Atsortingbutes.html .

Eh bien, printf parsing définitivement la chaîne de format au moment de l’exécution afin de faire son travail. Mais il n’est écrit nulle part que le compilateur ne peut choisir de l’parsingr lui-même s’il le souhaite.

La documentation de -Wformat indique que c’est exactement ce qui se passe:

-Wformat

-Wformat=n

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. Cela inclut les fonctions standard et d’autres spécifiées par les atsortingbuts de format (voir Atsortingbuts de fonction) dans les strftime printf , scanf , strftime et strfmon (une extension X / Open et non dans la norme C) (ou d’autres familles spécifiques à une cible). Les fonctions vérifiées sans que les atsortingbuts de format aient été spécifiés dépendent de la version standard sélectionnée. De telles vérifications de fonctions sans atsortingbut spécifié sont désactivées par -ffreestanding ou -fno-builtin .

Les formats sont vérifiés par rapport aux fonctionnalités de format supscopes par GNU libc version 2.2. Celles-ci incluent toutes les fonctionnalités ISO C90 et C99, ainsi que des fonctionnalités de la spécification Single Unix et certaines extensions BSD et GNU. D’autres implémentations de bibliothèque peuvent ne pas prendre en charge toutes ces fonctionnalités; GCC ne prend pas en charge l’avertissement concernant les fonctionnalités qui vont au-delà des limites d’une bibliothèque particulière. Cependant, si -Wpedantic est utilisé avec -Wformat, des avertissements sont donnés sur les fonctionnalités de format qui ne sont pas dans la version standard sélectionnée (mais pas pour les formats strfmon, car ceux-ci ne figurent dans aucune version de la norme C). Voir Options Contrôle du dialecte C.

Mise à jour: il s’avère que vous pouvez l’ utiliser pour vos propres fonctions. Mike a les détails .