web-dev-qa-db-fra.com

Pourquoi les variables inutilisées sont-elles un problème?

Un jour, je nettoyais les avertissements des variables inutilisées et j'ai commencé à réfléchir, quel est exactement le problème à leur sujet?

En fait, certains d'entre eux aident même au débogage (par exemple, inspectez les détails des exceptions ou vérifiez la valeur de retour avant le retour).

Je ne pouvais pas trouver réel réel risque de les avoir ..

Exemples

Je ne parle pas de lignes qui prennent du temps à l'attention des autres programmeurs, telles que:

int abc = 7;

C'est une redondance et une distraction évidentes. Je veux dire des trucs comme:

try {
    SomeMethod();
} catch (SomeException e) {
    // here e is unused, but during debug we can inspect exception details
    DoSomethingAboutIt();
}
9
Tar

Selon le cadre que vous avez donné, il est difficile de contester ces variables en soi:

try {
    SomeMethod();
} catch (SomeException e) {
// here e is unused, but during debug we can inspect exception details
DoSomethingAboutIt();
}

Prenez cela par exemple. Vous interceptez une exception et (peut-être) avez du code qui traite correctement l'exception. Le fait que vous n'utilisiez pas l'instance réelle de l'exception ne nuit pas, ni au flux de code, ni à la compréhensibilité.

Mais ce qui me fait penser, c'est quand vous écrivez sur la légitimation des "variables inutilisées"

En fait, certains d'entre eux aident même au débogage

Ce n'est pas le but d'écrire du code: devoir le déboguer plus tard. Afin d'éviter les malentendus, je dois dire, que je suis bien conscient, que vous devez souvent corriger votre code; et parfois le débogage est la solution. Mais ce ne devrait pas être le premier, ce qui vous vient à l'esprit, lors de l'écriture de code, que vous laissiez des "points d'ancrage", dont le seul but est de faciliter le débogage.

SomeClass Func() {
    // ...stuff...
    var ret = FinalComputationResult(thing, foo, bar);
    // ret is unused, but while debugging allows checking return value.
    return ret;
}

Ici, cela dépend de la complexité de stuff et de sa relation avec la valeur renvoyée.

En tant que "règle d'or", je dirais ce qui suit:

Si cela aide à comprendre le but du code, il est correct de supprimer la redondance dans votre code

ou pour le dire autrement:

Écrivez votre code aussi libre de redondance que nécessaire pour comprendre plus tard facilement ce que fait le code

Cela se traduit par: La plupart du temps, vous devez supprimer les variables "debug" .

4
Thomas Junk

Le plus gros problème est clarté. Si votre code contient un tas de déchets indésirables et que je maintiens votre code, je dois comprendre ce que tout fait.

Cette variable est-elle jamais utilisée pour quoi que ce soit? Peut-être que vous effectuez des opérations dessus, mais n'utilisez jamais sa valeur pour quelque chose. Le simple fait d'incrémenter une variable ne signifie pas que la variable sert un objectif si vous ne la lisez jamais (retour, entrée dans une autre expression, et al).

Cependant: si une variable a un but et est nommée de manière appropriée elle ne le fait pas pas nuire au code dans son ensemble.

Compte tenu des exemples de votre question mise à jour et de quelques autres auxquels j'ai pensé:

  • Avoir une fonction qui appelle une autre fonction, stocke le résultat, l'enregistre, puis la renvoie est assez courte et claire.

  • La division d'une instruction avec plusieurs expressions en plusieurs instructions (par exemple, la division d'un calcul long et complexe en plusieurs instructions avec plusieurs variables intermédiaires) peut rendre le code plus clair malgré être plus verbeux. Avec moins d'informations à traiter à la fois, le cerveau peut plus facilement comprendre ce qui se passe.

  • Ne pas utiliser d'exceptions est tout à fait correct: la plupart des langues nécessitent de spécifier l'exception à intercepter, y compris de fournir un nom de variable à utiliser dans le bloc catch. Il n'y a aucun moyen de contourner cela dans de nombreux langages populaires et les programmeurs y sont habitués.

Si je dois passer du temps à déterminer quels éléments de code ont un but et qui ne font que perdre mon temps, ma productivité diminue. Cependant, si le code est assez concis et que les variables sont bien nommées même si elles semblent être étrangères au début, cela réduit le risque de perdre du temps inutile à revoir le code pour le comprendre.

Un mauvais code avec des variables superflues, des blocs vides et du code mort est un moyen pour les développeurs d'avoir une mauvaise réputation au bureau: "Je corrigeais un bogue dans le code de Snowman. J'ai passé deux heures à comprendre ce que faisait cette fonction et trente secondes à corriger le bug! Snowman est terrible à la programmation! " Mais si le code sert un objectif et est écrit de manière claire, c'est parfaitement bien.

19
user22815

Les variables inutilisées rendent le intention de votre code peu clair. C'est mauvais car malgré les apparences, le code est principalement écrit pour personnes à lire, pas pour ordinateurs.

D'autres ont déjà souligné que la construction d'une valeur et son non-utilisation déroutent les autres personnes qui doivent lire et travailler avec votre code. Cependant, à mon avis, le plus grand danger est de vous-même.

Une variable inutilisée peut être intentionnelle, ou il peut s'agir d'un oubli pointant vers un défaut. Par exemple, vous avez peut-être mal saisi un nom et enregistré une valeur à un endroit lorsque vous pensiez l'avoir stocké à un autre. Le programme résultant pourrait fonctionner correctement mais donner silencieusement le mauvais résultat.

L'analyse du flux de données peut vous aider à trouver de telles erreurs et bien d'autres. Par conséquent, il est avantageux d'écrire votre code de telle manière que tout un analyseur de flux de données indique qu'une anomalie est, en fait, un bug. Une assistance automatique pour prévenir les bogues est inestimable; beaucoup de gens pensent "Oh, je n'ai pas besoin d'aide, je ne serais jamais aussi insouciant", mais jusqu'à présent, tous ceux que j'ai rencontrés qui pensaient que c'était mal.

5
Kilian Foth

Les variables inutilisées qui ne servent à rien sont une odeur de code à mon avis. Au mieux, ils peuvent être une distraction - ils ajoutent au bruit général dans le module.

Le pire des cas est que les codeurs suivants passent du temps à comprendre ce qu'il était censé faire et à se demander si le code est complet. Faites-vous plaisir (et à tous les autres) et débarrassez-vous.

5
Robbie Dee

Il existe un style de codage qui consiste à affecter délibérément tout ce qui était (ou pourrait devenir) intéressant une variable dans le but spécifique de la regarder facilement dans un débogueur. Ceci est particulièrement utile pour le code qui ressemble à:

return foo(bar(), baz(wot(12), wombat(&badger)));

Même avec des noms un peu meilleurs pour les fonctions, il peut être plus facile de déterminer ce qui ne va pas dans l'appel à foo lorsqu'il est écrit comme suit:

auto awombat = wombat(&badger);
auto awot = wot(12);
auto abaz = baz(awot, abadger);
auto abar = bar();
auto afoo = foo(abar, abaz);
return afoo;

Je n'ai pas encore travaillé avec des gens qui pratiquent cela comme configuration par défaut, mais réécrire un morceau de code qui refuse obstinément de donner un sens à formulaire d'attribution unique peut faciliter la tâche pour déterminer ce qui se passe sous le débogueur. Nous avons toujours restitué le code au format compact, "joli" par la suite, mais je me demande si c'était une erreur.

L'alternative consiste à monter et descendre la pile et à espérer que vous n'allez pas trop loin, ou à utiliser des débogueurs réversibles (ce qui est extrêmement rare).

Ce n'est pas une stratégie populaire, mais comme cela m'a aidé à surmonter certains bugs absurdes, je ne pense pas qu'elle devrait être considérée comme intrinsèquement mauvaise.

2
Jon Chesterfield

Pour les personnes qui incluent leur code de test unitaire dans les mêmes projets ou modules que leur "vrai" code, un champ inutilisé, comme une méthode d'objet, est un signal fort que vos tests unitaires ne testent pas tout . Cela augmente les chances qu'un développeur essaie d'utiliser ce champ ou cette méthode actuellement inutilisé et rencontre un bogue qui n'était pas détecté jusque-là.

Une variable inutilisée dans un sous-programme ou une méthode quelque peu banale peut indiquer que le programmeur avait l'intention de l'utiliser, mais utilise une autre variable par erreur (par exemple, après le nettoyage après une opération de copier-coller).

Une variable inutilisée dans un sous-programme plus trivial est probablement soit des scories inutiles, comme l'ont répondu d'autres personnes. Parfois, il est utilisé dans une instruction de fil d'Ariane actuellement commentée:

SomeObject tmp = someMethod();
// printDebugInfoAbout (tmp);

... il est clair pour le globe oculaire qu'il est utilisé là-bas, et seulement là (c'est-à-dire que someMethod a un effet secondaire important), mais le IDE ne le sait pas, et supprimer cette variable est plus difficile que cela en vaut la peine. J'utilise provisoirement des suppresseurs d'avertissement dans ces cas.

1
Paul Brinkley

Il est facile lorsque vous écrivez du code de mélanger deux variables. Vous calculez une variable B mais utilisez ensuite à la place une variable A créée précédemment.

Donc, une raison possible pour une variable inutilisée est qu'il y a une erreur dans votre code. C'est pourquoi le compilateur vous avertit. Si vous "ne faites pas" de variables inutilisées, c'est même un cadeau mort.

Lorsque vous voyez un tel avertissement, vous devez vérifier votre code et le corriger ou supprimer la variable incriminée. Si vous ne le supprimez pas, vous cesserez de prêter attention à ces avertissements, et vous pourriez tout aussi bien les désactiver complètement. Mais alors vous finirez par perdre un après-midi à déboguer le code à cause d'une erreur stupide.

0
Florian F