65 votes

Pourquoi $a + ++$a == 2 ?

Si j'essaie ceci :

$a = 0;    
echo $a + ++$a, PHP_EOL;
echo $a;

J'obtiens ce résultat :

2
1

Démonstration : http://codepad.org/ncVuJtJu

Comment cela se fait-il ?

Je m'attends à obtenir ce résultat :

1
1

Ce que je comprends :

$a = 0;                    // a === 0    
echo $a + ++$a, PHP_EOL;   // (0) + (0+1) === 1
echo $a;                   // a === 1

Mais pourquoi n'est-ce pas le cas ?

113voto

interjay Points 51000

Toutes les réponses expliquant pourquoi vous obtenez 2 et non 1 sont en fait fausses. D'après la documentation de PHP, le fait de mélanger + y ++ de cette manière est un comportement non défini, vous pouvez donc obtenir 1 ou 2. Le passage à une version différente de PHP peut changer le résultat que vous obtenez, et il serait tout aussi valide.

Voir exemple 1 qui dit :

// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5

Notes :

  1. La préséance des opérateurs ne pas déterminer l'ordre d'évaluation. La préséance des opérateurs détermine uniquement si l'expression $l + ++$l est analysé comme $l + (++$l) mais ne détermine pas si l'opérande gauche ou droit de la fonction + est évalué en premier. Si l'opérande gauche est évalué en premier, le résultat sera 0+1, et si l'opérande droit est évalué en premier, le résultat sera 1+1.

  2. L'associativité des opérateurs ne détermine pas non plus l'ordre d'évaluation. Le fait que l'opérateur + a l'associativité gauche ne détermine que $a+$b+$c est évaluée comme suit ($a+$b)+$c . Il ne détermine pas l'ordre dans lequel les opérandes d'un opérateur unique sont évalués.

Également pertinent : Sur ce rapport de bogue concernant une autre expression avec des résultats indéfinis, un développeur PHP dit : "Nous ne garantissons pas l'ordre d'évaluation [...], tout comme le C ne le fait pas. Pouvez-vous nous indiquer un endroit dans la documentation où il est indiqué que le premier opérande est évalué en premier ?"

66voto

Dennis Points 1410

L'opérateur de préincrémentation "++" intervient avant l'évaluation du reste de l'expression dans laquelle il se trouve. C'est donc en fait :

echo $l + ++$l; // (1) + (0+1) === 2

24voto

hakre Points 102271
a + b

a = 1
b = ++a

:= 2

Pourquoi attendez-vous autre chose ?

En PHP :

$a = 0;
$c = $a + ++$a;

Préséance de l'opérateur visualisée :

$c = ($a) + (++$a);

Visualisation de la séquence d'évaluation :

$a = 0; ($a = 0)
$a = 1; (++$a)
$c = $a + $a (1 + 1);

ou de la suppression d'une partie de son contenu :

Au moment où l'opération de somme est effectuée, $a est déjà 1 car ++$a a déjà été évaluée. Les ++ est évalué avant l'opérateur + de l'opérateur.


Pour le plaisir :

$a++ + ++$a

Résultats en 2, aussi. Cependant, si vous les comparez en tant qu'expression, elles ne sont pas égales :

$a++ + ++$a == $a + ++$a

Où comme

$a++ + ++$a == $a-- + --$a 

est "égal".


Voir aussi

7voto

NikiC Points 47270

Mon Ordre d'évaluation en PHP Un article de blog explique cela en détail, mais voici l'idée de base :

  • Préséance de l'opérateur et l'associativité n'ont rien à voir avec l'ordre d'évaluation.
  • PHP ne garantit pas un ordre d'évaluation. L'ordre peut changer entre les versions de PHP sans préavis et peut également être différent en fonction du code environnant.
  • "Normalement, PHP évalue de gauche à droite, à l'exception des accès aux variables "simples" (comme $a ). Les accès aux variables simples seront exécutés après les expressions plus complexes, quel que soit l'ordre dans lequel elles apparaissent.
  • Dans ce cas particulier, cela signifie que ++$a est exécutée en premier parce qu'il s'agit d'une expression complexe et ce n'est qu'ensuite que la valeur de $a est récupéré (il est déjà à 1 à ce stade). Il s'agit donc en fait de la somme de 1 + 1 = 2 .
  • La raison pour laquelle les variables simples sont récupérées après les expressions complexes est l'optimisation des variables compilées (CV). Si vous désactivez cette optimisation, par exemple en utilisant l'option @ toutes les expressions sont évaluées de gauche à droite, y compris les simples extractions de variables.
  • Dans ce cas particulier, cela signifie que @($a + ++$a) se traduira par 1 parce que d'abord $a est récupéré (0 à ce moment-là) et n'est incrémenté qu'ensuite.

6voto

John3136 Points 12125

++ est l'opérateur le plus prioritaire, il est donc appliqué en premier.

Alors maintenant l = 1.

Donc 1 + 1 = 2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X