Perl:虽然没有条件

Eug*_*ash 44 perl while-loop

根据doc,while只要表达式为true,语句就会执行块.我想知道为什么它变成一个带有空表达式的无限循环:

while () { # infinite loop
 ...
}
Run Code Online (Sandbox Code Playgroud)

它只是文档中的不准确吗?

TLP*_*TLP 36

$ perl -MO=Deparse -e 'while () { }'
while (1) {
    ();
}
-e syntax OK
Run Code Online (Sandbox Code Playgroud)

看来,while () {}while (1) {}是等价的.另请注意,空的parens*将插入空块中.

预定义编译器行为的另一个示例:

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

我想说这只是没有报告特殊情况的文件.

* - 确切地说,stub插入了操作码.它什么都不做,但为enterloop操作码提供了goto目标.没有真正的理由要注意这一点.Deparse表示此stubop使用空的parens,因为parens不生成代码.

  • 奇怪的是,`for(;;)`也称为`while(1)`. (12认同)
  • @briandfoy是的,我注意到发布后这个..另一个特例.更奇怪的是`for()`是一个语法错误,但`for(())`编译,但不编译成`while(1)`case,但`foreach $ _(())`. (3认同)
  • @brian d foy,所有`for(;;){...}`,`while(){...}`和`while(TRUE){...}`编译成无条件循环( `loop {...}`).Deparse无法知道原始代码是什么. (2认同)

Sin*_*nür 14

这是Vacuous Truth概念的一个特例.如果没有条件,则条件为真时的语句本身就是真实的.

如果我正确阅读,相关的代码片段似乎在5.14.1的第5853行op.c:

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;
Run Code Online (Sandbox Code Playgroud)

我假设没有expr条件,我们到达o = listop.listop以前被定义为listop = op_append_list(OP_LINESEQ, block, cont);.


Mic*_*ade 11

这是一个特例.空条件表达式默认为just true,这意味着"永远循环,或直到a break.在C(和perl)中的成语

for(;;) {
   // Neverending fun
}
Run Code Online (Sandbox Code Playgroud)

出于同样的原因也有同样的效果.

在官方的perl文档中似乎没有提到这一点,但解析器中有一个特殊的规则.也许是因为没人用它:)

这个for(;;)成语虽然不那么罕见.

  • 这不是默认值.我刚检查了解析器代码.它有一个特殊的解析规则. (5认同)
  • 如果是,那肯定需要在文档中提及. (4认同)