a = (a + b) – (b = a); C ++ vs php

Я искал и нашел формулу: a = (a + b) - (b = a) предполагается, что в некоторых случаях они заменяют две переменные (или объекты). Однако я тестировал его с помощью C ++ и php, это дало мне другой результат.

PHP:

 $a = 10; $b = 20; $a = ($a + $b) - ($b = $a); echo $a, " ", $b; 

Это печатает 20 10

C ++

 int a = 10; int b = 20; a = (a + b) - (b = a); std::cout << a << " " << b; 

Это печатает 10 10

Код выглядит одинаково, но результаты разные, я думал о двух причинах:

  1. C ++-код компилируется и php интерпретирует.
  2. Эта формула бесполезна, поскольку ведет к неопределенному поведению.

Может ли кто-нибудь объяснить, почему C ++ и php-выход отличаются в этой ситуации?

Solutions Collecting From Web of "a = (a + b) – (b = a); C ++ vs php"

Я не уверен, что такое правила в PHP, но на C ++ порядок отдельных подвыражений строго не определен или, как технический термин, «неуказан» – другими словами, компилятор разрешен для вычисления b = a до или после него a + b . Пока он делает a + b и b = a перед вычитанием. Использование «неуказанного» поведения позволяет компилятору создавать более эффективный код в некоторых случаях или просто создавать компилятор для некоторых архитектур.

Это также означает, что если у вас есть выражение, которое «пересчитывает» значение внутри самого выражения, а также использует его в другом месте выражения, вы получаете неопределенное поведение (короткое замыкание в UB). UB означает именно это, поведение не определено – почти все может случиться, в том числе то, что вы видите, и многие другие альтернативы (например, компилятору также разрешено производить 42, даже если логика говорит, что ответ не будет 42 в этом случае [это неправильный вопрос для этого!]).

Я бы также предположил, что если вы захотите обменять два значения, в PHP:

  $t = $a; $a = $b; $b = $t; 

и в C ++:

  #include <algorithm> std::swap(a, b); 

или если вы настаиваете на написании своих собственных:

  int t = a; a = b; b = t; 

Попытка быть умной и выполнять ее «без временной переменной» почти наверняка сделает ее медленнее, чем использование временного – конечно, на компилируемом языке, таком как C ++, – на интерпретируемом языке, таком как PHP, создание новой переменной может добавить немного дополнительных накладных расходов, но это вряд ли будет таким большим, по сравнению с дополнительными усилиями в требуемой логике.

Код C ++ полностью разрушен из-за неопределенного поведения. (чтение и запись b в одной точке последовательности).

Для PHP:

 $a = 10; $b = 20; $a = ($a + $b) - ($b = $a); //executes like thus $a = (30) - ($b = $a); $a = (30) - ($b = $a = 10); //new $a still not computed, using older $a $a = (30) - (10); $a = 20; //then, $a=20 and $b = 10 

Это полностью связано с приоритетом оператора , это может быть одинаковым на C или не может, это зависит от приоритета, если непредвиденное поведение не происходит.