Perl: в то время как без условного
В соответствии с doc оператор while
выполняет блок до тех пор, пока выражение true. Интересно, почему он становится бесконечным циклом с пустым выражением:
while () { # infinite loop
...
}
Это неточность в документе?
Ответы
Ответ 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(;;)
менее редка.