Selon le doc le while
L'instruction exécute le bloc tant que l'expression est vrai . Je me demande pourquoi cela devient une boucle infinie avec une expression vide :
while () { # infinite loop
...
}
Est-ce juste une imprécision dans le doc ?
$ perl -MO=Deparse -e 'while () { }'
while (1) {
();
}
-e syntax OK
Il semble que while () {}
y while (1) {}
sont équivalentes. Notez également que les parenthèses vides* sont insérées dans le bloc vide.
Un autre exemple de comportement prédéfini du compilateur :
$ perl -MO=Deparse -e 'while (<>) { }'
while (defined($_ = <ARGV>)) {
();
}
-e syntax OK
Je dirais que c'est juste la documentation qui ne signale pas un cas particulier.
* - Pour être précis, le stub
L'opcode est inséré. Il ne fait rien, mais sert de cible de goto pour l'option enterloop
opcode. Il n'y a pas de réelle raison de le noter. Deparse dénote ce stub
opter pour l'utilisation de parenthèses vides, puisque les parenthèses ne génèrent pas de code.
Il s'agit d'un cas particulier du concept de Vacuité de la vérité . S'il n'y a pas de condition, la déclaration tant que la condition est vraie est elle-même vide de sens.
Si je lis correctement, le morceau de code pertinent semble être le suivant autour de la ligne 5853 de op.c
en 5.14.1 :
5853 if (expr) {
5854 scalar(listop);
5855 o = new_logop(OP_AND, 0, &expr, &listop);
5856 if (o == expr && o->op_type == OP_CONST && !SvTRUE(cSVOPo->op_sv)) {
5857 op_free(expr); /* oops, it's a while (0) */
5858 op_free((OP*)loop);
5859 return NULL; /* listop already freed by new_logop */
5860 }
5861 if (listop)
5862 ((LISTOP*)listop)->op_last->op_next =
5863 (o == listop ? redo : LINKLIST(o));
5864 }
5865 else
5866 o = listop;
Je suppose que sans expr
dans la condition, on arrive à o = listop
. listop
était précédemment défini comme listop = op_append_list(OP_LINESEQ, block, cont);
.
Il s'agit d'un cas particulier. Une expression de condition vide donne par défaut juste true
ce qui signifie "tourner en boucle pour toujours, ou jusqu'à ce qu'une break
. En C (et en perl) l'idiome
for(;;) {
// Neverending fun
}
a le même effet pour la même raison.
Il ne semble pas y avoir de mention de cela dans la documentation officielle de perl, et pourtant il y a une règle spéciale dans l'analyseur pour cela. C'est peut-être parce que personne ne l'utilise :)
Le site for(;;)
L'idiome est cependant moins rare.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.