Depuis que je suis instruit si dur dans le rapport de bug, je vais essayer de vous l'expliquer moi-même.
Imaginez T
est un certain type défini par l'utilisateur avec un cast implicite d' bool
qui alterne entre false
et true
, en commençant par false
. Aussi loin que le compilateur sait, l' dynamic
premier argument pour le premier &&
peut évaluer à ce type, de sorte qu'il a d'être pessimiste.
Si, ensuite, il laissait le code de la compilation, ce qui peut se produire:
- Lorsque la dynamique liant évalue la première
&&
, il effectue les opérations suivantes:
- Évaluer le premier argument
- C'est un
T
- implicitement la convertir en bool
.
- Oh, c'est
false
, de sorte que nous n'avons pas besoin d'évaluer le deuxième argument.
- Rendre le résultat de l'
&&
évaluer en tant que premier argument. (Non, pas false
, pour une raison quelconque.)
- Lorsque la dynamique liant évalue le deuxième
&&
, il effectue les opérations suivantes:
- Évaluer le premier argument.
- C'est un
T
- implicitement la convertir en bool
.
- Oh, c'est
true
, afin d'évaluer le deuxième argument.
- ... Oh merde,
b
n'est pas affecté.
Dans spec termes, en bref, il existe des "définitive" d'assignation des règles qui nous permettent de dire si une variable est "certainement affecté" ou "certainement pas attribué", mais aussi si elle est "définitivement attribuée après l' false
déclaration" ou "certainement attribuée après l' true
déclaration".
Il en existe un, de sorte que lorsque vous traitez avec des &&
et ||
(et !
et ??
et ?:
), le compilateur peut examiner si les variables peuvent être affectés, en particulier les branches d'un complexe expression booléenne.
Cependant, ces travaux seulement tandis que les expressions " types restent booléenne. Lors de la partie de l'expression est - dynamic
(ou un non-booléenne de type statique) on ne peut plus fiable de dire que l'expression est - true
ou false
- la prochaine fois que nous convertir en bool
afin de décider quelle direction prendre, il peut avoir changé son esprit.