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

后端 未结 4 1865
天涯浪人
天涯浪人 2021-01-01 09:41

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

#include 
using namespace std;

class Simple
{
public:
    s         


        
4条回答
  •  情歌与酒
    2021-01-01 10:33

    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.

提交回复
热议问题