44

ドキュメントによると、式がtruewhileである限り、ステートメントはブロックを実行します。なぜ空の式で無限ループになるのだろうか:

while () { # infinite loop
 ...
}

ドキュメントが間違っているだけですか?

4

3 に答える 3

36
$ 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オペコードが挿入されます。何もしませんが、enterloopオペコードの goto ターゲットを提供します。これに注意する本当の理由はありません。stub括弧はコードを生成しないため、deparse は空の括弧を使用してこのop を示します。

于 2012-04-26T12:42:58.853 に答える
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;

条件にno があると仮定するとexpr、 に到達しo = listopます。listopとして以前に定義されていましlistop = op_append_list(OP_LINESEQ, block, cont);た。

于 2012-04-26T15:16:29.687 に答える
11

これは特殊なケースです。空の条件式のデフォルトは justtrueです。これは、「永遠にループするか、または a までループすることを意味しますbreak。C (および perl) のイディオムでは、

for(;;) {
   // Neverending fun
}

同じ理由で同じ効果があります。

公式の perl ドキュメントにはこれについて言及されていないようですが、パーサーには特別なルールがあります。おそらく、誰もそれを使用していないためです:)

ただし、for(;;)イディオムはあまり一般的ではありません。

于 2012-04-26T12:27:23.707 に答える