Je reçois l'avertissement de troncation de format gcc suivant:
test.c:8:33: warning: ‘/input’ directive output may be truncated writing 6 bytes into a region of size between 1 and 20 [-Wformat-truncation=]
snprintf(dst, sizeof(dst), "%s-more", src);
^~~~~~
test.c:8:3: note: ‘snprintf’ output between 7 and 26 bytes into a destination of size 20
snprintf(dst, sizeof(dst), "%s-more", src);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sur le code comme ceci:
char dst[20];
char src[20];
scanf("%s", src);
snprintf(dst, sizeof(dst), "%s-more", src);
printf("%s\n", dst);
Je suis conscient du fait qu'il peut être tronqué - mais c'est exactement la raison pour laquelle j'utilise snprintf. Existe-t-il un moyen de faire comprendre au compilateur que cela est prévu (sans utiliser pragma ni troncation -Wno-format)?
Le niveau 1 de -Wformat-truncation [...] met en garde uniquement à propos des appels aux fonctions liées dont la valeur de retour n'est pas utilisée et qui entraînera très probablement une troncature de la sortie.
La troncature de sortie non gérée est généralement un bogue du programme. [...]
Dans les cas où une troncature est attendue, l'appelant vérifie généralement la valeur de retour de la fonction et la gère d'une manière ou d'une autre (par exemple, en y créant une branche). Dans ces cas, l'avertissement n'est pas émis. La ligne source imprimée par l'avertissement suggère qu'il ne s'agit pas de l'un de ces cas. L'avertissement fait ce pour quoi il a été conçu.
#include <stdio.h>
#include <stdlib.h>
void f(void) {
char dst[2], src[2];
// snprintf(dst, sizeof(dst), "%s!", src);
int ret = snprintf(dst, sizeof(dst), "%s!", src);
if (ret < 0) {
abort();
}
// But don't we love confusing one liners?
for (int ret = snprintf(dst, sizeof(dst), "%s!", src); ret < 0;) exit(ret);
// Can we do better?
snprintf(dst, sizeof(dst), "%s!", src) < 0 ? abort() : (void)0;
// Don't we love obfuscation?
#define snprintf_nowarn(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0)
snprintf_nowarn(dst, sizeof(dst), "%s!", src);
}
Testé sur https://godbolt.org/ avec gcc7.1 gcc7.2 gcc7.3 gcc8.1 avec -O{0,1,2,3} -Wall -Wextra -pedantic
. Ne donne aucun avertissement. gcc8.1 optimise/supprime l'appel à abort()
avec une optimisation supérieure à -O1
.
Vous pouvez ajouter un spécificateur de précision. Ceci imprimera au plus 14 caractères de src
en évitant une possible troncature de la chaîne de format et ne déclenchera pas cet avertissement:
snprintf(dst, sizeof(dst), "%.14s-more", src);