Подтвердить что ты не робот

Perl: в то время как без условного

В соответствии с doc оператор while выполняет блок до тех пор, пока выражение true. Интересно, почему он становится бесконечным циклом с пустым выражением:

while () { # infinite loop
 ...
}

Это неточность в документе?

4b9b3361

Ответ 1

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

Кажется, что while () {} и while (1) {} эквивалентны. Также обратите внимание, что пустые парсеры * вставляются в пустой блок.

Другой пример предопределенного поведения компилятора:

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

Я бы сказал, что это только документы, не сообщающие о специальном случае.

* — Если быть точным, вставляется код операции stub. Он ничего не делает, но служит для цели goto для кода операции enterloop. Нет никаких оснований для этого. Deparse обозначает этот stub op, используя пустые парсеры, поскольку parens не генерируют код.

Ответ 2

Это особый случай концепции Непростая правда. Если условие нет, утверждение, пока условие истинно, само по себе является недействительным.

Если я читаю это правильно, соответствующий фрагмент кода выглядит вокруг строки 5853 op.c в 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 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;

Я предполагаю, что при условии expr в условии мы достигаем o = listop. listop ранее был определен как listop = op_append_list(OP_LINESEQ, block, cont);.

Ответ 3

Это особый случай. По умолчанию пустое выражение условия имеет только true, что означает "цикл навсегда" или до break. В C (и perl) идиома

for(;;) {
   // Neverending fun
}

имеет тот же эффект по той же причине.

В официальных perl-документах не упоминается об этом, но в этом синтаксическом анализаторе есть специальное правило. Возможно, потому, что никто не использует его:)

Идиома for(;;) менее редка.