According to the doc, the while
statement executes the block as long as the expression is true. I wonder why it becomes an infinite loop with an empty expression:
This is a special case. An empty condition expression defaults to just true
, which means "loop forever, or until a break
. In C (and perl) the idiom
for(;;) {
// Neverending fun
}
has the same effect for the same reason.
There doesn't appear to be any mention of this in the official perl docs, and yet there is a special rule in the parser for it. Perhaps it's because nobody uses it :)
The for(;;)
idiom is less uncommon though.
This is a special case of the concept of Vacuous Truth. If there is no condition, the statement while the condition is true is itself vacuously true.
If I am reading this correctly, the relevant piece of code seems to be around line 5853 of op.c in 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;
I am assuming with no expr
in the condition, we reach o = listop
. listop
was previously defined as listop = op_append_list(OP_LINESEQ, block, cont);
.
$ perl -MO=Deparse -e 'while () { }'
while (1) {
();
}
-e syntax OK
It seems that while () {}
and while (1) {}
are equivalent. Also note that empty parens* are inserted in the empty block.
Another example of pre-defined compiler behaviour:
$ perl -MO=Deparse -e 'while (<>) { }'
while (defined($_ = <ARGV>)) {
();
}
-e syntax OK
I would say that this is just the docs not reporting a special case.
* — To be precise, the stub
opcode is inserted. It does nothing, but serves a goto target for the enterloop
opcode. There's no real reason to note this. Deparse denotes this stub
op using empty parens, since parens don't generate code.