44 votes

Perl : while sans conditionnel

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 ?

36voto

TLP Points 48922
$ 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.

14voto

Sinan Ünür Points 76179

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); .

11voto

Michael Slade Points 9128

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.com

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.

Powered by:

X