C ++运算符优先级(意外结果)

时间:2014-01-15 20:46:35

标签: c++ c++-cli

在使用VS 2010 / C ++交换两个变量的值的练习中,编译器“不”返回表达式的预期结果。

我理解一个更有效的表达式 - XOR x和y。本练习是使用代数表达式获得x和y的类似结果的另一种方法。

预期结果:x = 21,y = 11 样本CPP的结果是:x = 11,y = 11

// test.cpp : main project file.

#include "stdafx.h"

using namespace System;

int main(array<System::String ^> ^args)
{

    int x = 11; 
    int y = 23;

    x = (y+x) - (y = x);
    Console::WriteLine(System::String::Format("Value of x:", x));
    Console::WriteLine(System::String::Format("Value of y:", y));

    x = 11;
    y = 23;
    x = ((y+x)*1) - (y = x);
    Console::WriteLine(System::String::Format("Value of x:", x));
    Console::WriteLine(System::String::Format("Value of y:", y));

    return 0; 
}

ILDASM输出如下:

.method assembly static int32  main(string[] args) cil managed
{
 // Code size       118 (0x76)
   .maxstack  2
   .locals ([0] int32 y,
            [1] int32 x,
            [2] int32 V_2)
    IL_0000:  ldc.i4.0
    IL_0001:  stloc.2
    IL_0002:  ldc.i4.s   11
    IL_0004:  stloc.1
    IL_0005:  ldc.i4.s   23
    IL_0007:  stloc.0
    IL_0008:  ldloc.1
    IL_0009:  stloc.0
    IL_000a:  ldloc.0
    IL_000b:  ldloc.1
    IL_000c:  add
    IL_000d:  ldloc.0
    IL_000e:  sub
    IL_000f:  stloc.1
    IL_0010:  ldstr      "Value of x:"
    IL_0015:  ldloc.1
    IL_0016:  box        [mscorlib]System.Int32
    IL_001b:  call       string [mscorlib]System.String::Format(string,
                                                              object)
    IL_0020:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0025:  ldstr      "Value of y:"
    IL_002a:  ldloc.0
    IL_002b:  box        [mscorlib]System.Int32
    IL_0030:  call       string [mscorlib]System.String::Format(string,
                                                              object)
    IL_0035:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_003a:  ldc.i4.s   11
    IL_003c:  stloc.1
    IL_003d:  ldc.i4.s   23
    IL_003f:  stloc.0
    IL_0040:  ldloc.1
    IL_0041:  stloc.0
    IL_0042:  ldloc.0
    IL_0043:  ldloc.1
    IL_0044:  add
    IL_0045:  ldloc.0
    IL_0046:  sub
    IL_0047:  stloc.1
    IL_0048:  ldstr      "Value of x:"
    IL_004d:  ldloc.1
    IL_004e:  box        [mscorlib]System.Int32
    IL_0053:  call       string [mscorlib]System.String::Format(string,
                                                              object)
    IL_0058:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_005d:  ldstr      "Value of y:"
    IL_0062:  ldloc.0
    IL_0063:  box        [mscorlib]System.Int32
    IL_0068:  call       string [mscorlib]System.String::Format(string,
                                                              object)
    IL_006d:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0072:  ldc.i4.0
    IL_0073:  stloc.2
    IL_0074:  ldloc.2
    IL_0075:  ret
} // end of method 'Global Functions'::main

1 个答案:

答案 0 :(得分:3)

您的代码有未定义的行为。

x = (y+x) - (y = x);

y分配中修改y = x以及在y中阅读y+x的值的副作用是无序的。你不能假设它们发生在另一个之前。除此之外,该标准明确指出这会导致不确定的行为。

参考:2011 ISO C ++标准,第1.9节[intro.execution],第15段:

  

除非另有说明,否则评估各个运营商的操作数   并且个别表达的子表达式没有被排序。 [...]   对运算符的操作数的值计算进行排序   在运算符结果的值计算之前。如果一方   对标量对象的影响相对于另一个对象没有统计   对同一个标量对象的副作用或使用该值的计算值   相同标量对象的值,行为未定义。