Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ and PHP vs C# and Java - unequal results

I found something a little strange in C# and Java. Let's look at this C++ code:

#include <iostream> using namespace std;  class Simple { public:     static int f()     {         X = X + 10;         return 1;     }      static int X; }; int Simple::X = 0;  int main() {     Simple::X += Simple::f();     printf("X = %d", Simple::X);     return 0; } 

In a console you will see X = 11 (Look at the result here - IdeOne C++).

Now let's look at the same code on C#:

class Program {     static int x = 0;      static int f()     {         x = x + 10;         return 1;     }      public static void Main()     {         x += f();         System.Console.WriteLine(x);     } } 

In a console you will see 1 (not 11!) (look at the result here - IdeOne C# I know what you thinking now - "How that is possible?", but let's go to the following code.

Java code:

import java.util.*; import java.lang.*; import java.io.*;  /* Name of the class has to be "Main" only if the class is public. */ class Ideone {     static int X = 0;     static int f()     {         X = X + 10;         return 1;     }     public static void main (String[] args) throws java.lang.Exception     {         Formatter f = new Formatter();         f.format("X = %d", X += f());         System.out.println(f.toString());     } } 

Result the same as in C# (X = 1, look at the result here).

And for the last time let's look at the PHP code:

<?php class Simple {     public static $X = 0;      public static function f()     {         self::$X = self::$X + 10;         return 1;     } }  $simple = new Simple(); echo "X = " . $simple::$X += $simple::f(); ?> 

Result is 11 (look at the result here).

I have a little theory - these languages (C# and Java) are making a local copy of static variable X on the stack (are they ignoring the static keyword?). And that is reason why result in those languages is 1.

Is somebody here, who have other versions?

like image 809
Dmitry K. Avatar asked Aug 15 '14 08:08

Dmitry K.


People also ask

Is PHP and C similar?

In terms of keywords and language syntax, PHP is similar to the C style syntax. if conditions, for and while loops, and function returns are similar in syntax to languages such as C, C++, C#, Java and Perl.

Does PHP use C?

PHP is written in C, not C++. Why don't you take a peek in the PHP source code and see for yourself? no it does not translate anything into c++, although facebook developed a compiler that does translate PHP into C code, and then into machine language, called hiphop or someting like that.

Which one is better PHP or C#?

It is used for Windows phone apps, tools, and even cross-platform mobile frameworks (MONO). C# is an object-oriented programming language whereas PHP is NOT. Even with 31% growth, C# has attained 7th place in Stackoverflow 2019 survey and maintains a lead over PHP.


1 Answers

The C++ standard states:

With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator. —end note ]

§5.17 [expr.ass]

Hence, as in the same evaluation you use X and a function with a side effect on X, the result is undefined, because:

If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

§1.9 [intro.execution]

It happens to be 11 on many compilers, but there is no guarantee that a C++ compiler won't give you 1 as for the other languages.

If you're still skeptical, another analysis of the standard leads to the same conclusion: THe standard also says in the same section as above:

The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.

In you case X = X + f() except that X is evaluated only once.
As there is no guarantee on the order of evaluation, in X + f(), you cannot take for granted that first f is evaluated and then X.

Addendum

I'm not a Java expert, but the Java rules clearly specify the order of evaluation in an expression, which is guaranteed to be from left to right in section 15.7 of Java Language Specifications. In section 15.26.2. Compound Assignment Operators the Java specs also say that E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)).

In your Java program this means again that your expression is equivalent to X = X + f() and first X is evaluated, then f(). So the side effect of f() is not taken into account in the result.

So your Java compiler doesn't have a bug. It just complies with the specifications.

like image 159
Christophe Avatar answered Sep 21 '22 13:09

Christophe