Quel est l'avantage d'un do-while (faux)?
-
22-07-2019 - |
Question
Lorsque je regarde un code qui a été manipulé par un autre employé, je vois beaucoup de code écrit en:
do{
...
}while(false);
Quel avantage (le cas échéant) cela procure-t-il?
Voici plus d'un squelette qui se passe dans le code:
try{
do{
// Set some variables
for(...) {
if(...) break;
// Do some more stuff
if(...) break;
// Do some more stuff
}
}while(false);
}catch(Exception e) {
// Exception handling
}
Mise à jour:
Version C ++:
Les boucles do-while-false sont-elles courantes?
La solution
Peut-être que cela a été fait pour pouvoir sortir de la "boucle" à tout moment, par exemple:
do
{
...
if (somethingIsWrong) break;
//more code
...
}
while(false);
Mais comme d’autres l’ont dit, je ne le ferais pas comme ça.
Autres conseils
En Java, il n'y a aucune raison de le faire.
En C, il s'agit d'un langage courant lors de la définition de macros:
Considérez:
#define macro1 doStuff(); doOtherStuff()
#define macro2 do{ doStuff(); doOtherStuff(); } while( false )
if( something ) macro1; // only the first statement in macro1 is executed conditionally
if( something ) macro2; // does what it looks like it does
... mais les macros en C sont pervers et doivent être évités autant que possible.
Votre collègue est-il issu d’un milieu C?
Aucun avantage. Ne le fais pas.
Il peut être utilisé pour aller à la fin d'un bloc et éviter un groupe imbriqué de blocs if / then.
do {
if (done()) continue;
// do a bunch of stuff
if (done()) continue;
// do a bunch more stuff
if (done()) continue;
// do even more stuff
} while (false);
Ceci est utilisé en C pour définir un bloc dans une macro. Voir ceci par exemple.
Exemple, ce qui suit n'est pas valide:
#define f(x) { g(x); h(x); }
if (x >= 0) f(x); else f(-x);
mais avec cette définition, cela fonctionnera:
#define f(x) do { g(x); h(x) } while(false)
Cela ne sert à rien, mais le codeur aurait pu utiliser plusieurs commandes d'interruption pour gérer certaines exceptions bizarres.
do{
if(<something>){...}else{break}
if(<something else>){...}else{break}
...
}while(false)
Certes, c'est stupide, mais j'ai trouvé quelque chose comme dans un vieux programme c une fois
Votre intuition est juste. C’est une chose complètement inutile.
Il est possible que la personne qui l'a codé à l'origine ait utilisé autre chose que false
et l'a simplement remplacée par false
plutôt que de la supprimer. le bloc entier ne doit pas perdre cette " historique " du code. Ceci est juste un accrochage à la paille cependant. Pour être tout à fait franc, c’est un exemple typique de tautologie , qui n'a pas placer dans le code.
Dans à peu près tous les langages autres que le C / C ++, cela ne fournit aucun avantage tactique.
En C / C ++, il existe un cas de macros dans lequel l'opération do / while (false) facilite l'extension d'une macro en toute sécurité en plusieurs instructions. Ceci est avantageux lorsque la macro ressemble autrement à un appel de fonction normal.
Consultez cette question
Le PO demande des informations sur cette construction exacte et explique certaines des raisons de son utilisation. Le consensus semble être que c'est une mauvaise chose à faire.
En tant qu'espace réservé pour un futur lorsqu'une autre condition est remplacée par false
.
Cela pourrait être utilisé pour ignorer l'exécution de certains codes (comme un goto
ou quelque chose du genre), mais lorsque je le regarde à nouveau, il semble qu'il y ait un pour
en boucle ( où les instructions if (...) break;
sont) dans le faire-tout
. Sinon, je dirais que ce serait une version Java d'un goto
...
J'ai utilisé cette convention pendant des années! C’est très utile lorsque vous avez un "pipeline". des traitements et / ou des contrôles conditionnels. Cela évite simplement plusieurs niveaux d'instructions if () imbriquées et rend ainsi le code (beaucoup) plus facile à lire. Oui, il existe des alternatives telles que try / catch et je n’utilise ce style que dans certaines situations de niveau faible / faible.
Je lance la " boucle " (ne fait jamais de boucle) avec un commentaire comme ...
// Error loop (never loops)
La boucle d'erreur est ...
set errorCode = fail;
do {
if (this)
break;
if (that)
break;
// Success
set errorCode = ok;
// Alternative Success
errorCode = doWhatever();
} while (false);
Considérez ce style si vous avez un tas d'instructions if () imbriquées et que vos retraits vont à plus de 3 niveaux.
J'ai utilisé cette convention en Perl, C / C ++, Java et Delphi / Pascal.
Je vais deviner que l'auteur de celui-ci ne faisait pas confiance à son code, il le lançait donc plusieurs fois pour voir si cela le rendait plus performant et s'il en restait les vestiges archéologiques.
La seule raison à laquelle je peux penser est de créer un bloc pour que les variables déclarées dans {...}
soient plus étroitement définies, mais il existe de meilleures façons de le faire (comme créer des fonctions, par exemple). ou tout simplement créer des blocs - chapeau à Pete Kirkham).