PHP5.3のクロージャの謎というかPHPだから謎なんてない!な挙動

zend_compile.c を読んでいて気づいた。

<?php
$b = 2;

$a = function() use ($b) {
    if (false) { static $b = 4; }
    var_dump($b);
};

$a();
?>

これの結果が

int(4)

となる。摩訶不思議。

みんな大嫌いなクロージャのuseキーワードは、5.1から導入されたcompiled variables(CV)という、ローカル変数アクセス高速化のための機構の実装が腐っているために導入されたといっていいと思う。こいつはオートグローバルを除くすべてのvariableに対するアクセスを、たとえそれがreadのみだったとしてもCV化してしまう。本来ならassignmentが行われるまではfree variableとして扱える余地を残しておくべき。

ちなみにcompiled variableについてはSara Golemonのこのエントリを見てください。

まーPHP書かないんだけどね。