En C et C ++, il est très facile d'écrire le code suivant avec une grave erreur.
char responseChar = getchar();
int confirmExit = 'y' == tolower(responseChar);
if (confirmExit = 1)
{
exit(0);
}
L'erreur est que l'instruction if aurait dû être:
if (confirmExit == 1)
Comme codé, il se fermera à chaque fois, car l'affectation de la confirmExit
variable se produit, puis confirmExit
est utilisée comme résultat de l'expression.
Existe-t-il de bons moyens pour éviter ce type d'erreur?
c++
coding-standards
DeveloperDon
la source
la source
if (confirmExit)
.a = b
ou à l'a == b
intérieur d'un conditionnel.Réponses:
La meilleure technique consiste à augmenter le niveau d'avertissement de votre compilateur. Il vous avertira alors d'une affectation potentielle dans le cas conditionnel.
Assurez-vous de compiler votre code sans aucun avertissement (ce que vous devriez faire de toute façon). Si vous voulez être pédant, configurez votre compilateur pour traiter les avertissements comme des erreurs.
L'utilisation des conditions Yoda (en mettant la constante sur le côté gauche) était une autre technique qui était populaire il y a une dizaine d'années. Mais ils rendent le code plus difficile à lire (et donc à maintenir en raison de la façon non naturelle dont ils lisent (sauf si vous êtes Yoda)) et n'offrent pas plus d'avantages que d'augmenter le niveau d'avertissement (qui a également des avantages supplémentaires de plus d'avertissements).
Les avertissements sont vraiment des erreurs logiques dans le code et doivent être corrigés.
la source
if (0 == ret)
horreur.a == b
!!0==a && 0==b || 1==a && 1==b || 2==a && 2==b || ...
(répétez pour toutes les valeurs possibles). N'oubliez pas l'...|| 22==a && 22==b || 23==a && 24==b || 25==a && 25==b ||
erreur obligatoire ... sinon les programmeurs de maintenance ne s'amuseront pas.Vous pouvez toujours faire quelque chose de radical comme tester votre logiciel. Je ne parle même pas de tests unitaires automatisés, juste les tests que chaque développeur expérimenté fait par habitude en exécutant son nouveau code deux fois, une fois confirmant la sortie et une fois non. C'est la raison pour laquelle la plupart des programmeurs considèrent qu'il ne s'agit pas d'un problème.
la source
rc=MethodThatRarelyFails(); if(rc = SUCCESS){
plus d'une fois, surtout si la méthode échoue uniquement dans des conditions difficiles à tester.Une manière traditionnelle d'empêcher l'utilisation incorrecte des affectations dans l'expression consiste à placer la constante à gauche et la variable à droite.
Le compilateur signalera une erreur pour l'affectation illégale à une constante similaire à la suivante.
La condition if révisée serait:
Comme le montrent les commentaires ci-dessous, cela est considéré par beaucoup comme une méthode inappropriée.
la source
Je suis d'accord avec tout le monde qui dit "avertissements du compilateur" mais je veux ajouter une autre technique: les revues de code. Si vous avez une politique de révision de tout le code qui est validé, de préférence avant qu'il ne soit validé, il est probable que ce genre de chose sera détecté lors de la révision.
la source
Tout d'abord, augmenter vos niveaux d'avertissement ne fait jamais de mal.
Si vous ne voulez pas que votre conditionnel teste le résultat d'une affectation dans l'instruction if elle-même, alors avoir travaillé avec de nombreux programmeurs C et C ++ au fil des ans et n'avoir jamais entendu cela en comparant la constante en premier
if(1 == val)
était une mauvaise chose, vous pourrait essayer cette construction.Si votre chef de projet approuve votre décision, ne vous inquiétez pas de ce que les autres pensent. La vraie preuve est de savoir si vous ou quelqu'un d'autre pouvez donner un sens à votre code dans des mois et des années à partir de maintenant.
Si vous aviez l'intention de tester le résultat d'une affectation, cependant, l'utilisation d'avertissements plus élevés aurait [probablement aurait] pu affecter l'affectation à une constante.
la source
if ( auto myPtr = dynamic_cast<some_ptr>(testPtr) ) {
qu'elle évite de garder unenullptr
portée inutile si le transtypage échoue - ce qui est probablement la raison pour laquelle C ++ a cette capacité limitée à attribuer dans un conditionnel. Pour le reste, oui, une définition devrait avoir sa propre ligne, je dirais - beaucoup plus facile à voir en un coup d'œil et moins sujette à des glissements de tête assortis.Toujours en retard à la fête, mais l'analyse du code statique est la clé ici
La plupart des IDE fournissent désormais SCA au-delà de la vérification syntaxique du compilateur, et d'autres outils sont disponibles, y compris ceux qui implémentent les directives MISRA (*) et / ou CERT-C.
Déclaration: Je fais partie du groupe de travail MISRA C, mais je poste à titre personnel. Je suis également indépendant de tout fournisseur d'outils
la source
Utilisez simplement l'affectation à gauche, les avertissements du compilateur peuvent vous aider, mais vous devez vous assurer d'obtenir le bon niveau, sinon vous serez submergé d'avertissements inutiles ou on ne vous dira pas ceux que vous souhaitez voir.
la source