Comment élever avertissement si la valeur de retour est ignorée?
J'aimerais voir toutes les endroits dans mon code (C++) qui ne tiennent pas compte de la valeur de retour d'une fonction. Comment puis-je le faire - avec gcc ou statique outil d'analyse de code?
Mauvais exemple de code:
int f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}
int main()
{
int i = 7;
f(i); /////<<----- here I disregard the return value
return 1;
}
Veuillez noter que:
- il devrait fonctionner même si la fonction et son utilisation sont dans des fichiers différents
- gratuit statique l'outil de vérification
- Cela permettra d'imprimer beaucoup de mises en garde si vous utilisez
printf
par exemple. - Le "probable" raison, il ne peut pas être exécutée via la ligne de commande, c'est que si vous avez une raison valable pour ignorer un résultat, alors vous vous retrouvez avec la nécessité d'attribuer un "unused variable", qui devrait générer un avertissement. Par exemple, vous ne voulez certainement pas
T& operator=(T rhs);
pour vous forcer à récupérer le résultat 😉 - M: Vous n'avez pas besoin d'allouer une variable muette quand vous voulez ignorer la valeur de retour d'une fonction. Tout simplement jeté l'appel à la fonction nulle, comme dans
(void) function_returning_a_val();
. Lors de la lecture du code, cela rend également plus claire que vous ignorer volontairement la valeur de retour. [[nodiscard]]
en C++17.- Depuis cela ressemble le plus ancien et le plus upvoted question sur ce sujet, j'ai ajouté une mise à jour de réponse couvrant C++17.
Vous devez vous connecter pour publier un commentaire.
Vous voulez du CCG
warn_unused_result
attribut:En essayant de compiler ce code produit:
Vous pouvez le voir dans l'utilisation de la Le noyau Linux; ils ont un
__must_check
macro qui fait la même chose; vous ressemble besoin de GCC 3.4 ou plus pour que cela fonctionne. Alors vous trouverez que les macro utilisé dans le noyau fichiers d'en-tête:Autant que je suis conscient qu'il n'existe pas de GCC avec l'option de donner cet avertissement. Toutefois, si vous êtes intéressé à des fonctions spécifiques, vous pouvez les marquer avec un attribut:
qui permettrait de donner un avertissement si la valeur de retour de la fn() n'a pas été utilisé. Mise en garde: je n'ai jamais utilisé cette fonctionnalité moi-même.
Vous pouvez utiliser à portée de main ce modèle pour le faire au moment de l'exécution.
Au lieu de retourner un code d'erreur (par exemple, HRESULT) vous retournez un return_code<HRESULT>, qui affirme que si elle est hors de portée sans la valeur en cours de lecture. Ce n'est pas un outil d'analyse statique, mais il est utile néanmoins.
bool
.Pour C++17 la réponse à cette question change puisque nous avons maintenant la [[nodiscard]] attribut. Couverts en [dcl.attr.nodiscard]:
et
Afin de modifier votre exemple (voir en direct):
Maintenant nous obtenir un diagnostic avec gcc et clang par exemple
Toute analyse statique de code (par exemple,PC-Lint) devrait être en mesure de vous le dire. Pour PC-Lint, je sais que c'est le cas.
un analyseur statique va faire le travail pour vous, mais si votre base de code est plus trivial préparez-vous à être submergé 😉
Un analyseur statique sera votre meilleur pari ici. Nous utilisons Coverity ici, mais il y a des outils gratuits disponibles que vous pouvez utiliser.
Si vous avez besoin d'un quick-and-dirty solution et vous avez un Linux-shell de type à portée de main, vous pouvez essayer quelque chose comme:
Qui vous permettra de trouver chaque ligne qui fait référence à la fonction spécifiée, mais ne contient pas un "=". Vous pouvez obtenir un grand nombre de faux positifs (et éventuellement quelques faux négatifs), mais si vous ne disposez pas d'un analyseur statique c'est un endroit décent pour commencer.
Le classique "peluches" programme utilisé pour être très volubile sur les fonctions qui a retourné une valeur qui a été ignorée. Le problème est, la plupart de ces mises en garde étaient indésirables conduisant à l'excès de bruit dans la fibre de sortie (il était de ramasser les peluches que vous vouliez de l'ignorer). C'est probablement pourquoi GCC n'est pas un avertissement standard pour elle.
L'autre problème - le revers de la médaille - est "comment voulez-vous supprimer l'avertissement quand vous savez que vous êtes ignorant dans le résultat mais n'a vraiment pas de soins". Le scénario classique pour ce qui est:
Vous vous souciez de la première suite de
signal()
; vous savez que le second sera SIG_IGN (puisque vous suffit de le définir à qui). Pour obtenir à partir des mises en garde, j'utilise parfois quelques variantes sur:Il attribue à
old
les deux fois. Vous pouvez suivre qu'avec les " assert(ancien == SIG_IGN)'.void
, par exemple(void)printf("Hello, world!\n");
Même au plus haut niveau d'avertissement, pas d'avertissement sera émis pour cette avec le cast explicite nulle.(void)
" cast fonctionne...c'est laid dans le code. Et j'ai eu à regarder après le code qui remplace cette vilaine-gramme avec 'VOID
"à la place; elle correspond à'(void)
" cast Standard avec les compilateurs C (tous les compilateurs C ces jours-ci), mais son origine dans les jours avant qu'ils ont été la norme et puis en fait des choses avec l'affectation du résultat dans un fichier statique de la variable ('#define VOID _void_ =
"ou quelque chose du genre). Aaah; les souvenirs, et les cerceaux qui a dû être sauté à travers.