В соответствии с doc оператор while
выполняет блок до тех пор, пока выражение true. Интересно, почему он становится бесконечным циклом с пустым выражением:
while () { # infinite loop
...
}
Это неточность в документе?
В соответствии с doc оператор while
выполняет блок до тех пор, пока выражение true. Интересно, почему он становится бесконечным циклом с пустым выражением:
while () { # infinite loop
...
}
Это неточность в документе?
$ 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 не генерируют код.
Это особый случай концепции Непростая правда. Если условие нет, утверждение, пока условие истинно, само по себе является недействительным.
Если я читаю это правильно, соответствующий фрагмент кода выглядит вокруг строки 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);
.
Это особый случай. По умолчанию пустое выражение условия имеет только true
, что означает "цикл навсегда" или до break
. В C (и perl) идиома
for(;;) {
// Neverending fun
}
имеет тот же эффект по той же причине.
В официальных perl-документах не упоминается об этом, но в этом синтаксическом анализаторе есть специальное правило. Возможно, потому, что никто не использует его:)
Идиома for(;;)
менее редка.