Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I've been looking around and found formula: a = (a + b) - (b = a) it is supposed to swap two variables (or objects in some cases). However I tested it with C++ and php, these gave me different result.

php:

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

This prints 20 10

C++

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

This prints 10 10

Code looks the same but outputs are different, I've been thinking about two reasons:

  1. C++ code is compiling and php is interpreting.
  2. This formula is useless because it leads to undefined behavior.

Can somebody explains, why C++ and php output differs in this situation?

like image 630
ST3 Avatar asked Aug 04 '13 07:08

ST3


2 Answers

I'm not sure what the rules are in PHP, but in C++, the order of individual sub-expressions isn't strictly defined, or as the technical term is, it is "unspecified" - in other words, the compiler is allowed to calculate b = a before or after it does a + b. As long as it does a + b and b = a before the subtraction. The use of "unspecified" behaviour allows the compiler to produce more efficient code in some cases, or simply that it's possible to build a compiler for some architectures.

It also means that if you have an expression that "recalculates" a value within the expression itself, and also using it elsewhere in the expression, you get unedefined behaviour (UB for short). UB means just that, the behaviour is not defined - almost anything could happen, including what you are seeing and many other alternatives (e.g. the compiler is allowed to produce 42 as a result as well, even if logic says the answer wouldn't be 42 in this case [it's the wrong question for that!]).

I would also suggest that if you want to swap two values, in PHP:

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

and in C++:

 #include <algorithm>

 std::swap(a, b); 

or if you insist on writing your own:

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

Trying to be clever and perform it "without temporary variable" is almost certainly going to make it slower than the use of a temporary - certainly in a compile language like C++ - in a interpreted language like PHP, creating a new variable may add a bit of extra overhead, but it's unlikely to be that big, compared to the extra effort in the logic required.

like image 93
Mats Petersson Avatar answered Sep 28 '22 09:09

Mats Petersson


C++ code is completely broken because of undefined behavior. (read and write b in one sequence point).

like image 41
MAnyKey Avatar answered Sep 28 '22 08:09

MAnyKey