Perl: sans conditionnel

Selon le document , l’instruction while exécute le bloc tant que l’expression est vraie . Je me demande pourquoi cela devient une boucle infinie avec une expression vide:

 while () { # infinite loop ... } 

Est-ce juste une inexactitude dans la doc?

 $ perl -MO=Deparse -e 'while () { }' while (1) { (); } -e syntax OK 

Il semble que while () {} et while (1) {} sont équivalents. Notez également que les parens vides * sont insérés dans le bloc vide.

Autre exemple de comportement prédéfini du compilateur:

 $ perl -MO=Deparse -e 'while (<>) { }' while (defined($_ = )) { (); } -e syntax OK 

Je dirais que ce ne sont que les médecins qui ne signalent pas un cas particulier.

* – Pour être précis, l’opcode stub est inséré. Il ne fait rien, mais sert une cible goto pour l’opcode enterloop . Il n’y a pas de vraie raison de le noter. Deparse dénote ce stub op utilisant des parens vides, puisque les parens ne génèrent pas de code.

Ceci est un cas particulier du concept de Vérité Vacuelle . S’il n’y a pas de condition, l’affirmation alors que la condition est vraie est elle-même véridiquement vraie.

Si je lis ceci correctement, le morceau de code correspondant semble être autour de la ligne 5853 de l’ op.c dans 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 sans expr dans la condition, nous atteignons o = listop . listop était précédemment défini comme listop = op_append_list(OP_LINESEQ, block, cont); .

Ceci est un cas particulier. Une expression de condition vide par défaut est simplement true , ce qui signifie “boucle pour toujours, ou jusqu’à une break . En C (et perl)

 for(;;) { // Neverending fun } 

a le même effet pour la même raison.

Il ne semble pas y avoir de mention de cela dans les documents officiels de perl, et pourtant, il existe une règle spéciale dans l’parsingur correspondant. C’est peut-être parce que personne ne l’utilise 🙂

L’idiome for(;;) est cependant moins rare.