[Outil de vérification de code statique C/C++ Cppcheck] Liste des détecteurs Cppcheck et des règles d'inspection


Activer/désactiver l'inspecteur

Cppcheck vous permet d'activer ou de désactiver des vérificateurs spécifiques via des arguments de ligne de commande. Vous pouvez utiliser --enable=des paramètres pour activer des inspecteurs spécifiques ou utiliser --disable=des paramètres pour désactiver des inspecteurs spécifiques.

Par exemple, si vous souhaitez uniquement activer les vérifications liées à la mémoire, vous pouvez utiliser la commande suivante :

cppcheck --enable=warning,performance,portability,information,missingInclude --suppress=missingIncludeSystem yourfile.cpp

Cette commande activera tous les avertissements, les performances, la portabilité, les vérifications d'information et d'inclusion manquante, mais supprimera les avertissements d'inclusion manquante du système.

Vous pouvez trouver plus d'informations sur l'utilisation de ces paramètres dans le manuel officiel de Cppcheck . Le but de chaque paramètre et comment les utiliser est décrit en détail dans le manuel.

Notez que vous devez choisir les inspecteurs à activer ou désactiver en fonction de vos besoins. Tous les inspecteurs ne conviennent pas à toutes les situations, vous devez donc choisir l'inspecteur approprié en fonction de votre code et des problèmes que vous souhaitez vérifier.

Recherche de fuites de mémoire

La vérification des fuites de mémoire de Cppcheck est activée par défaut et ne peut pas être désactivée individuellement.

Si vous souhaitez vérifier les fuites de mémoire, vous devez utiliser --enable=all ou ne pas utiliser le paramètre --enable, car la vérification des fuites de mémoire est activée par défaut.

liés aux performances

Cppcheck peut vérifier certains problèmes liés aux performances. Vous pouvez activer les vérifications liées aux performances à l'aide de la commande suivante :

cppcheck --enable=performance yourfile.cpp

Cette commande activera les vérifications liées aux performances et n'activera pas les autres vérificateurs.

L'inspection des performances peut vous aider à trouver des problèmes susceptibles d'affecter l'efficacité de votre code, tels que des variables inutilisées, des valeurs de retour de fonction inutilisées et des modèles de programmation pouvant entraîner une dégradation des performances.

Notez cependant que même si Cppcheck peut vous aider à détecter certains problèmes de performances, il ne remplace pas une analyse complète des performances. Si vous devez effectuer une analyse approfondie des performances, vous devrez peut-être utiliser des outils d'analyse de performances spécialisés, tels que gprof, Callgrind de Valgrind ou Intel VTune, etc.

Vous pouvez trouver plus d'informations sur l'utilisation de ces paramètres dans le manuel officiel de Cppcheck .

vérificateur par défaut

Les vérificateurs par défaut de Cppcheck incluent :

  • Erreur : ce type de vérificateur détecte principalement les problèmes susceptibles de provoquer un plantage ou une exécution anormale du programme, tels que des fuites de mémoire, des tableaux hors limites, des variables non initialisées, etc.
  • Avertissement : Ce type de vérificateur détecte principalement les problèmes qui peuvent amener le programme à se comporter moins bien que prévu, mais pas nécessairement provoquer le plantage du programme, tels que les fonctions inutilisées, les variables inutilisées, etc.

Les deux types d'inspecteurs sont activés par défaut et ne peuvent pas être désactivés.

Pour les autres vérificateurs, tels que le style (style), les performances (performance), la portabilité (portabilité), etc., vous pouvez --enableactiver ou désactiver via des paramètres. Par exemple, si vous souhaitez activer tous les vérificateurs, vous pouvez utiliser --enable=allle paramètre.

autre

  1. Formats de sortie prédéfinis : Cppcheck prend en charge plusieurs formats de sortie prédéfinis, y compris ceux compatibles avec Visual Studio et gcc. Vous pouvez utiliser l'option --template=vsou --template=gccpour obtenir une sortie dans ces formats.

  2. Formats de sortie définis par l'utilisateur : Vous pouvez créer vos propres formats de sortie. Par exemple, vous pouvez utiliser --template="{file}:{line}: {severity}: {message}"pour créer des formats de message d'avertissement similaires à gcc traditionnels.

  3. Plugins : Cppcheck prend en charge l'utilisation de plugins pour des vérifications supplémentaires. Par exemple, misra.pyles plugins peuvent être utilisés pour vérifier que le code est conforme à la norme MISRA C 2012, un ensemble de spécifications de code développé pour les systèmes embarqués. Vous pouvez utiliser --addon=misra.pydes options pour activer ce plugin.

  4. Configuration de la bibliothèque : Lors de l'utilisation de bibliothèques externes (telles que WinAPI, POSIX, gtk, Qt, etc.), Cppcheck peut ne pas connaître le comportement de ces fonctions externes. Vous pouvez utiliser des fichiers .cfg pour configurer le comportement de ces bibliothèques afin d'aider Cppcheck à détecter les problèmes avec plus de précision.

  5. Rapports HTML : Vous pouvez convertir la sortie XML de Cppcheck en rapports HTML. Vous avez besoin de Python et du module pygments pour que cela fonctionne. Dans l'arborescence des sources de Cppcheck, il existe un dossier appelé htmlreport qui contient un script qui convertit les fichiers XML de Cppcheck en sortie HTML.

  6. Niveaux de vérification : Cppcheck possède deux niveaux de vérification : normal et exhaustif. La vérification de niveau normale est la valeur par défaut et vise à fournir une vérification efficace dans un délai "raisonnable". Un niveau de vérification exhaustif peut --check-level=exhaustiveêtre activé via des options, ce qui peut être plus utile dans les situations où vous pouvez attendre les résultats.

  7. Accélération de l'analyse : Il existe des moyens d'accélérer l'analyse de Cppcheck, comme limiter la configuration du préprocesseur, limiter le nombre maximum de si de ValueFlow, ou utiliser diverses options dans l'interface graphique pour limiter l'analyse.

vérificateur

Vous pouvez obtenir une liste actuelle de tous les inspecteurs implémentés via l'application en ligne de commande :

# 获取检查器列表
cppcheck --doc

# 获取错误消息列表
cppcheck --errorlist

liste de contrôle

Portabilité 64 bits

Vérifiez les problèmes de portabilité 64 bits :

  • assigner l'adresse à/de int/long
  • Convertir l'adresse de/en entier au retour de la fonction

Affirmation

Avertir s'il y a des effets secondaires dans une instruction assert (car cela peut entraîner un comportement différent dans les versions debug/release).

variable automatique

Un pointeur vers une variable n'est valide que lorsque la variable est dans la portée. examiner:

  • renvoie un pointeur sur une variable automatique ou temporaire
  • Affecter l'adresse d'une variable à un paramètre valide d'une fonction
  • Renvoie une référence à une variable locale/temporaire
  • Renvoie l'adresse du paramètre de la fonction
  • Affectation suspecte de paramètres de pointeur
  • Affectation inutile des paramètres de fonction

Valeur booléenne

Vérification du type booléen :

  • Incrémenter une valeur booléenne
  • compare une expression booléenne à un entier autre que 0 ou 1
  • Utiliser des opérateurs relationnels pour comparer des fonctions qui renvoient des valeurs booléennes
  • Comparer booléen à booléen à l'aide d'opérateurs relationnels
  • Utilisation de valeurs booléennes dans les expressions binaires
  • Ajout de pointeur dans la condition (soit oublier de déréférencer, soit avoir besoin d'un débordement de pointeur pour rendre la condition fausse)
  • attribuer une valeur booléenne au pointeur ou au flotteur
  • Renvoyer un entier autre que 0 ou 1 à partir d'une fonction renvoyant un booléen

Augmenter l'utilisation

Vérifiez les utilisations non valides de Boost :

  • Modifier le conteneur dans BOOST_FOREACH

Vérification des limites

Vérification hors limites :

  • Index de tableau hors limites
  • débordement arithmétique du pointeur
  • débordement de tampon
  • Utilisation dangereuse de strncat()
  • Utiliser l'index du tableau avant de vérifier
  • Une écriture de chaîne partielle a entraîné un tampon non terminé par zéro.
  • Vérifiez si un tableau suffisamment grand est passé à la fonction
  • allouer de la mémoire avec une taille négative

Vérifier l'utilisation de la fonction

Vérifier l'utilisation de la fonction :

  • 'retour' manquant dans la fonction non vide
  • Ne pas utiliser la valeur de retour de certaines fonctions
  • valeur d'entrée invalide pour la fonction
  • Avertir si une fonction dont l'utilisation est interdite est appelée
  • Le troisième paramètre de memset() est zéro
  • Le deuxième argument de memset() est hors limites
  • Le deuxième paramètre de memset() est un nombre à virgule flottante
  • Optimisation par élimination de copie de std :: move sur la valeur de retour
  • Utilisez memcpy()/memset() au lieu de la boucle for

type

Consultez le code pour chaque classe :

  • constructeur manquant et constructeur de copie
  • Doit être un constructeur explicite
  • Toutes les variables sont-elles initialisées par le constructeur ?
  • Toutes les variables sont-elles affectées par 'operator=' ?
  • Avertir si memset, memcpy, etc. sont utilisés sur une classe
  • Si de la mémoire a été allouée pour la classe, si malloc() a été utilisé
  • S'il s'agit d'une classe de base, vérifiez si le destructeur est virtuel
  • Y a-t-il des fonctions privées inutilisées ?
  • 'operator=' doit vérifier l'auto-attribution
  • constance des fonctions membres
  • ordre d'initialisation
  • Il est recommandé d'utiliser la liste d'initialisation
  • initialiser le membre avec lui-même
  • Soustraction suspecte de "ceci"
  • Appel d'une fonction virtuelle pure dans un constructeur/destructeur
  • Membres de données hérités en double
  • Vérifie si l'utilisation arbitraire de l'interface publique entraînera une erreur de division par zéro
  • supprimez le 'self pointeur' puis accédez à 'ceci'
  • Vérifiez si le mot-clé 'override' est utilisé lors du remplacement d'une fonction virtuelle
  • Vérifiez si la "règle une fois définie" est violée

condition

Conditions correspondant aux affectations et autres conditions :

  • Affectation et comparaison incompatibles => la comparaison est toujours vrai/faux
  • lhs et rhs en comparaison ne correspondent pas => la comparaison est toujours vrai/faux
  • Détecter les cas où | doit être utilisé &
  • Conditions et affectations répétées
  • Détecter les conditions "if" et "else if" correspondantes
  • Bits incompatibles AND (a &= 0xf0; a &= 1; => a = 0)
  • Le contraire de la condition intérieure est toujours faux
  • La même condition après une sortie anticipée est toujours fausse
  • condition toujours vrai/faux
  • Un mutex via || est toujours évalué à true
  • Toujours vrai/faux modulo le résultat de la comparaison.
  • Valeur variable connue => la condition est toujours vrai/faux
  • Test de débordement invalide. Certains compilateurs traditionnels suppriment ces tests de débordement lors de l'optimisation du code.
  • Allocation suspecte de conteneur/itérateur dans condition => la condition est toujours vraie.

sécurité exceptionnelle

Vérifiez la sécurité des exceptions :

  • Lancer une exception dans le destructeur
  • lever une exception dans un état invalide
  • Lance une copie de l'exception interceptée au lieu de relancer l'exception d'origine
  • Attraper les exceptions par valeur au lieu de référence
  • Lever des exceptions dans les fonctions noexcept, nothrow(), attribute((nothrow)) ou __declspec(nothrow)
  • Spécification d'exception non gérée lors de l'appel de la fonction foo()
  • relance si aucune exception n'est en cours de traitement

IO utilisant des chaînes de format

Recherchez les opérations d'entrée/sortie qui utilisent des chaînes de format.

  • Utilisation incorrecte de la fonction 'sprintf' (données qui se chevauchent)
  • Spécificateur de largeur manquant ou incorrect dans la chaîne de format 'scanf'
  • utiliser le dossier fermé
  • L'entrée/sortie de fichier non localisée entraîne

comportement indéfini

  • Lire les fichiers qui ne sont ouverts qu'en écriture (et vice versa)
  • Effectuer des opérations de repositionnement sur les fichiers ouverts en mode ajout
  • Le même fichier ne peut pas être ouvert simultanément pour la lecture et l'écriture sur différents flux
  • Utilisez fflush() sur le flux d'entrée
  • Utilisation non valide du flux de sortie. Par exemple : 'std::cout << std::cout;'
  • Mauvais nombre d'arguments fournis à 'printf' ou 'scanf'

fuite (variable automatique)

Détecter lorsqu'une variable automatique est allouée mais non libérée ou est libérée deux fois.

fuite de mémoire (adresse non prise)

n'a pas obtenu l'adresse de la mémoire allouée

fuite de mémoire (variable de classe)

Si le constructeur alloue de la mémoire, le destructeur doit la libérer.

fuite de mémoire (variable de fonction)

Y a-t-il de la mémoire allouée lorsque la fonction sort de la portée

fuite de mémoire (membres de la structure)

N'oubliez pas de libérer les membres de la structure

pointeur nul

pointeur nul

  • déréférencement de pointeur nul
  • arithmétique de pointeur nul indéfinie

Voici la seconde partie de la liste des checkers Cppcheck :

autre

Autres contrôles :

  • diviser par zéro
  • Un objet délimité qui est détruit immédiatement après la construction
  • Affectations dans les déclarations d'assertion
  • free() ou delete pour libérer un emplacement mémoire invalide
  • opérations au niveau du bit avec des opérandes droits négatifs
  • Convertissez les valeurs de retour de getc(), fgetc() et getchar() en caractères et comparez avec EOF
  • Condition de concurrence avec accès non entrelacé après l'appel InterlockedDecrement()
  • L'expression 'x = x++;' dépend de l'ordre d'évaluation des effets secondaires
  • Écritures superposées combinées
  • Soit diviser par zéro ou condition inutile
  • Déplacer ou avancer l'accès aux variables.
  • Copie redondante des données des variables const
  • Affectations ou copies ultérieures de variables ou de tampons
  • Passer les paramètres par valeur
  • Passer un pointeur NULL à une fonction avec un nombre variable d'arguments provoque UB.
  • Conversion de pointeur de style C dans le code C++
  • conversion entre des types de pointeurs incompatibles
  • phrase incomplète
  • Vérifiez comment utiliser les variables char signées
  • La portée des variables peut être restreinte
  • Arithmétique de pointeur inhabituelle. Exemple : "abc" + 'd'
  • Affectation redondante, incrémentation ou manipulation de bits dans une instruction switch
  • Strcpy redondant dans l'instruction switch
  • Étiquettes de cas suspects dans switch()
  • affectation variable

Utilisation STL

Vérifiez l'utilisation non valide de la STL :

  • erreur hors limites
  • Utilisation abusive des itérateurs lors de l'itération sur un conteneur
  • incompatibilité de conteneur dans l'appel
  • le même itérateur dans l'appel
  • déréférence un itérateur supprimé
  • Pour les vecteurs : utilisez des itérateurs/pointeurs après avoir utilisé push_back
  • Optimisation : utilisez empty() au lieu de size() pour un code rapide
  • Conditions suspectes lors de l'utilisation de la recherche
  • Recherches inutiles dans les conteneurs associatifs
  • condition redondante
  • Erreurs courantes lors de l'utilisation de string ::c_str()
  • Appels inutiles aux fonctions string et STL
  • déréférencement d'un itérateur invalide
  • Lire à partir d'un conteneur STL vide
  • Itérer sur des conteneurs STL vides
  • Envisagez d'utiliser des algorithmes STL au lieu de boucles brutes
  • Verrouillage incorrect lors de l'utilisation d'un mutex

Taille de

sizeof() vérifie en utilisant

  • sizeof avec un tableau comme argument de la fonction
  • sizeof avec des valeurs numériques comme arguments de fonction
  • Utilisez sizeof(pointer) au lieu de la taille des données pointées
  • recherche 'taillede taillede...'
  • Trouver des calculs à l'intérieur de sizeof()
  • Trouver des appels de fonction à l'intérieur de sizeof()
  • Recherchez les calculs suspects de sizeof()
  • Utilisation de 'sizeof(void)', qui n'est pas défini

chaîne

Détectez l'utilisation abusive des chaînes de style C :

  • Chevauchement des tampons pour transmettre la source et la destination à sprintf
  • Mauvais argument de longueur pour 'substr' et 'strncmp'
  • Condition suspecte (comparaison d'exécution des littéraux de chaîne)
  • Conditions suspectes (littéraux chaîne/char comme booléens)
  • Comparaison suspecte de littéraux de chaîne avec des variables char*
  • Comparaison suspecte avec '\0' de la variable char*
  • Expressions strcmp() superposées

taper

vérification de type

  • décaler trop de bits (uniquement activé lors de l'utilisation de --platform)
  • débordement d'entier signé (uniquement activé lors de l'utilisation de --platform)
  • conversion de signe dangereuse lorsque la valeur signée peut être négative
  • perte possible d'informations lors de l'affectation d'un résultat int à une variable longue
  • Perte possible d'informations lors du retour d'un résultat int sous la forme d'une valeur de retour longue
  • débordement de conversion en virgule flottante

variable non initialisée

variable non initialisée

  • utilisation de variables locales non initialisées
  • Utiliser les données allouées avant l'initialisation

fonction inutilisée

Rechercher les fonctions qui ne sont jamais appelées

Var inutilisé

Vérification Var inutilisée

  • variable inutilisée
  • variables allouées mais inutilisées
  • variables non lues
  • variable non affectée
  • membres de structure inutilisés

utiliser l'opérateur postfixé

Avertir si les opérateurs postfixés ++ ou – sont utilisés à la place des opérateurs préfixés

Vaarg

Vérifiez l'utilisation abusive des listes d'arguments variables :

  • Passer de mauvais arguments à va_start()
  • Passez une référence à va_start()
  • va_end() manquant
  • Utilisez va_list avant d'ouvrir
  • Appels ultérieurs à va_start/va_copy()

Voici la liste complète des vérificateurs Cppcheck.

épilogue

La compréhension est une étape importante vers le niveau suivant dans notre parcours d'apprentissage de la programmation. Cependant, maîtriser de nouvelles compétences et idées demande toujours du temps et de la persévérance. D'un point de vue psychologique, l'apprentissage s'accompagne souvent d'essais et d'erreurs continus et d'ajustements, c'est comme si notre cerveau optimisait progressivement son « algorithme » pour résoudre les problèmes.

C'est pourquoi, lorsque nous rencontrons des erreurs, nous devons les voir comme des opportunités d'apprendre et de nous améliorer, pas seulement comme des obsessions. En comprenant et en résolvant ces problèmes, nous pouvons non seulement corriger le code actuel, mais aussi améliorer notre capacité de programmation et éviter que les mêmes erreurs ne se reproduisent dans de futurs projets.

J'encourage tout le monde à participer activement et à améliorer continuellement leurs compétences en programmation. Que vous soyez un débutant ou un développeur expérimenté, j'espère que mon blog pourra vous aider dans votre parcours d'apprentissage. Si vous trouvez cet article utile, vous pouvez cliquer pour le mettre en signet, ou laisser vos commentaires pour partager vos idées et vos expériences.Vous êtes également invités à faire des suggestions et des questions sur le contenu de mon blog. Chaque like, commentaire, partage et suivi est le plus grand soutien pour moi et la motivation pour moi de continuer à partager et à créer.


Lisez ma page d'accueil CSDN pour débloquer du contenu plus intéressant : page d'accueil CSDN de Bubble
insérez la description de l'image ici

おすすめ

転載: blog.csdn.net/qq_21438461/article/details/131650026