'static' value appears to reset after function call [duplicate]Behaviour and Order of evaluation in C#How exactly do static fields work internally?order of evaluation of operandsCan not round trip html format to clipboardList, not lose the reference Why is this Java code 6x faster than the identical C# code?WCF Guid DataMember not Serialized properlyHow to pass a sql connections string value to a C# programC# why object can't be converted to intStatic function returns unexpectedly when called from constructorExit a method back to Main?get set accessors from static Main() - and best practice for boolean storeWidth 100% and height 100% not working in chrome

My mysterious "ruins" wander around and change on their own, what'd be a rational way for them to do that?

What are standard cryptographic assumptions?

Travelling to Spain with a Kosovan passport, what are the outcomes if caught?

Unexpected Code Coverage Reduction

Is there any point in adding more than 6 months' runway in savings instead of investing everything after that?

How to use FDE without needing to share the encryption password

What is my volume?

Does milk make your bones stronger?

Theme or Topic - what's the difference?

Is a Senate trial required after the House impeaches a president?

Find peaks, max and min of an interpolation function?

How to avoid after work hours team dinner?

Prevent sleep if CPU usage is high

Why did a shuttle astronaut have an open book during ascent?

Does flying or hovering make creatures immune to the Earth Tremor spell?

"Chess is 90% tactics" - should a player focus more on tactics in order to improve?

50% portfolio in single stock, JPM - appropriate for 80 year old?

What does the 1.-5. notation mean at the top right corner?

Time machine in Interstellar movie

Was there a clearly identifiable "first computer" to use or demonstrate the use of virtual memory?

What type of rhetorical device is the offering of a source which is really long and not specifying what part of the source is relevant?

What's the link?

Perils of having a moon consisting of valuable material

What is the meaning of Text inside of AMS logo



'static' value appears to reset after function call [duplicate]


Behaviour and Order of evaluation in C#How exactly do static fields work internally?order of evaluation of operandsCan not round trip html format to clipboardList, not lose the reference Why is this Java code 6x faster than the identical C# code?WCF Guid DataMember not Serialized properlyHow to pass a sql connections string value to a C# programC# why object can't be converted to intStatic function returns unexpectedly when called from constructorExit a method back to Main?get set accessors from static Main() - and best practice for boolean storeWidth 100% and height 100% not working in chrome






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









88

















I found a lot of articles about statics (MSDN, MSDN 2, Stack Overflow, and lot lot more), but I still can't understand why this code returns -1:



class Program

static int value = 0;

static int foo()

value = value - 7;
return 1;


static void Main(string[] args)

value -= foo();
Console.WriteLine(value);
Console.ReadKey();




Here's what the debugger shows after foo() has run, but before the result is subtracted from value:



foo=1, value=-7



But one step later, value is -1:



value = -1



I would expect -8 because of the static field which is stored in memory once.



When I changed it to



var x = foo();
value -= x;


it shows -8



How does this work exactly?










share|improve this question























  • 9





    @pappbence96 which is exactly what he expects, but isn't getting.

    – TvanB
    Jul 23 at 7:28






  • 52





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    Jul 23 at 7:33






  • 8





    Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

    – EmerG
    Jul 23 at 7:36







  • 14





    value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

    – Archer
    Jul 23 at 7:43







  • 3





    Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

    – cmaster
    Jul 24 at 19:43

















88

















I found a lot of articles about statics (MSDN, MSDN 2, Stack Overflow, and lot lot more), but I still can't understand why this code returns -1:



class Program

static int value = 0;

static int foo()

value = value - 7;
return 1;


static void Main(string[] args)

value -= foo();
Console.WriteLine(value);
Console.ReadKey();




Here's what the debugger shows after foo() has run, but before the result is subtracted from value:



foo=1, value=-7



But one step later, value is -1:



value = -1



I would expect -8 because of the static field which is stored in memory once.



When I changed it to



var x = foo();
value -= x;


it shows -8



How does this work exactly?










share|improve this question























  • 9





    @pappbence96 which is exactly what he expects, but isn't getting.

    – TvanB
    Jul 23 at 7:28






  • 52





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    Jul 23 at 7:33






  • 8





    Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

    – EmerG
    Jul 23 at 7:36







  • 14





    value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

    – Archer
    Jul 23 at 7:43







  • 3





    Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

    – cmaster
    Jul 24 at 19:43













88












88








88


10






I found a lot of articles about statics (MSDN, MSDN 2, Stack Overflow, and lot lot more), but I still can't understand why this code returns -1:



class Program

static int value = 0;

static int foo()

value = value - 7;
return 1;


static void Main(string[] args)

value -= foo();
Console.WriteLine(value);
Console.ReadKey();




Here's what the debugger shows after foo() has run, but before the result is subtracted from value:



foo=1, value=-7



But one step later, value is -1:



value = -1



I would expect -8 because of the static field which is stored in memory once.



When I changed it to



var x = foo();
value -= x;


it shows -8



How does this work exactly?










share|improve this question

















I found a lot of articles about statics (MSDN, MSDN 2, Stack Overflow, and lot lot more), but I still can't understand why this code returns -1:



class Program

static int value = 0;

static int foo()

value = value - 7;
return 1;


static void Main(string[] args)

value -= foo();
Console.WriteLine(value);
Console.ReadKey();




Here's what the debugger shows after foo() has run, but before the result is subtracted from value:



foo=1, value=-7



But one step later, value is -1:



value = -1



I would expect -8 because of the static field which is stored in memory once.



When I changed it to



var x = foo();
value -= x;


it shows -8



How does this work exactly?







This question already has answers here:


Closed 4 months ago.






This question already has answers here:


Closed 4 months ago.




This question already has answers here:



Closed 4 months ago.




Behaviour and Order of evaluation in C# [duplicate]

(2 answers)





Behaviour and Order of evaluation in C# [duplicate]

(2 answers)






c#






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited Jul 25 at 22:08









J. Antonio Perez

6,80912 silver badges28 bronze badges




6,80912 silver badges28 bronze badges










asked Jul 23 at 7:24









EmerGEmerG

5226 silver badges11 bronze badges




5226 silver badges11 bronze badges










  • 9





    @pappbence96 which is exactly what he expects, but isn't getting.

    – TvanB
    Jul 23 at 7:28






  • 52





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    Jul 23 at 7:33






  • 8





    Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

    – EmerG
    Jul 23 at 7:36







  • 14





    value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

    – Archer
    Jul 23 at 7:43







  • 3





    Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

    – cmaster
    Jul 24 at 19:43












  • 9





    @pappbence96 which is exactly what he expects, but isn't getting.

    – TvanB
    Jul 23 at 7:28






  • 52





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    Jul 23 at 7:33






  • 8





    Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

    – EmerG
    Jul 23 at 7:36







  • 14





    value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

    – Archer
    Jul 23 at 7:43







  • 3





    Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

    – cmaster
    Jul 24 at 19:43







9




9





@pappbence96 which is exactly what he expects, but isn't getting.

– TvanB
Jul 23 at 7:28





@pappbence96 which is exactly what he expects, but isn't getting.

– TvanB
Jul 23 at 7:28




52




52





FYI, this has nothing to do with static.

– Ahmed Abdelhameed
Jul 23 at 7:33





FYI, this has nothing to do with static.

– Ahmed Abdelhameed
Jul 23 at 7:33




8




8





Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

– EmerG
Jul 23 at 7:36






Debuged this already , when method ends, value = -7, but step next it magically changed on "-1". Thas the problem which can't understand

– EmerG
Jul 23 at 7:36





14




14





value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

– Archer
Jul 23 at 7:43






value -= foo() is the same as value = current value of value (0) - foo() which returns 1, which is the same as value = 0 - 1. foo() does decrement value but only after you've referenced it in the calculation that calls foo(). Bad explanations have made it difficult to understand, but that's it in a nutshell.

– Archer
Jul 23 at 7:43





3




3





Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

– cmaster
Jul 24 at 19:43





Statements like i += i++; are inherently ambiguous in meaning. Some languages have legalese in place that makes such statements well-defined, other languages (infamously the C family) just say: "The order of operand evaluation is undefined." It doesn't matter what category your language falls in, code that's ambiguous in this way should not be written as it's hard to understand.

– cmaster
Jul 24 at 19:43












6 Answers
6






active

oldest

votes


















132



















This problem is not about static; it's about how the subtraction works.



value -= foo(); can be expanded to value = value - foo()



The compiler will explain it into four steps:



  1. Load the value of value onto the stack.

  2. Call the method foo and put the result onto the stack.

  3. Do subtraction with these two values on the stack.

  4. Set the result back to value field.

So the original value of value field is already loaded. Whatever you change value in the method foo, the result of the subtraction won't be affected.



If you change the order to value = - foo() + value, then the value of value field will be loaded after foo is called. The result is -8; that's what you are expected to get.



Thanks for Eliahu's comment.






share|improve this answer























  • 14





    If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

    – Eliahu Aaron
    Jul 23 at 8:17






  • 7





    @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

    – Norman Gray
    Jul 24 at 8:43






  • 12





    @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

    – shingo
    Jul 24 at 9:13






  • 3





    @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

    – Luaan
    Jul 25 at 7:57







  • 6





    @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

    – Jeppe Stig Nielsen
    Jul 25 at 11:33


















63



















The statement



value -= foo(); // short for value = value - foo();


is equivalent to



var temp = value; // 0
var fooResult = foo(); // 1
value = temp - fooResult; // -1


That's why you are getting -1






share|improve this answer























  • 11





    @Bahrom: It seems to work like you claim, but why?

    – Eliahu Aaron
    Jul 23 at 7:37







  • 16





    @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

    – Heinzi
    Jul 24 at 20:22


















34



















Just look at the generated CIL:



.method private hidebysig static int32 foo() cil managed

// Code size 19 (0x13)
.maxstack 2
.locals init ([0] int32 V_0)
IL_0000: nop
IL_0001: ldsfld int32 Program::'value'
IL_0006: ldc.i4.7
IL_0007: sub
IL_0008: stsfld int32 Program::'value'
IL_000d: ldc.i4.1
IL_000e: stloc.0
IL_000f: br.s IL_0011
IL_0011: ldloc.0
IL_0012: ret
// end of method Program::foo



  • IL_0001: - Push the value of the static field on the stack. s:[value(0)]


  • IL_0006: - Push 7 onto the stack. s:[7, value(0)]


  • IL_0007: - Subtracts value2 (7) from value1 (0), returning a new value (-7).


  • IL_0008: - Replaces the value of the static field with val (value = -7).


  • IL_000d: - Push 1 onto the stack. s:[1, 7, value(-7)]


  • IL_000e: - Pop a value from stack into local variable 0. (lv = 1)


  • IL_0011: - Load local variable 0 onto stack. s:[lv(1), 7, value(-7)]


  • IL_0012: - Return (lv(1))

And the Main method:



.method private hidebysig static void Main(string[] args) cil managed

.entrypoint
// Code size 29 (0x1d)
.maxstack 8
IL_0000: nop
IL_0001: ldsfld int32 Program::'value'
IL_0006: call int32 Program::foo()
IL_000b: sub
IL_000c: stsfld int32 Program::'value'
IL_0011: ldsfld int32 Program::'value'
IL_0016: call void [mscorlib]System.Console::WriteLine(int32)
IL_001b: nop
IL_001c: ret
// end of method Program::Main



  • IL_0001: - pushes value onto stack (which is 0)


  • IL_0006: - calls foo (which will return 1)


  • IL_000b: - subtract values: value2(1) from value1(0) (value(0) - value(1) = -1).

So the result is -1.






share|improve this answer



































    18



















    You can use menu DebugWindowsDisassembly and check what goes on in the background:



    I commented the most interesting parts.



     //static int value = 0;
    05750449 mov ebp,esp
    0575044B push edi
    0575044C push esi
    0575044D push ebx
    0575044E sub esp,2Ch
    05750451 xor edx,edx
    05750453 mov dword ptr [ebp-10h],edx
    05750456 mov dword ptr [ebp-1Ch],edx
    05750459 cmp dword ptr ds:[15E42D8h],0
    05750460 je 05750467
    05750462 call 55884370
    05750467 xor edx,edx
    05750469 mov dword ptr ds:[15E440Ch],edx // STEP_A place 0 in ds register
    somewhere
    0575046F nop
    05750470 lea esp,[ebp-0Ch]
    05750473 pop ebx
    05750474 pop esi
    05750475 pop edi
    05750476 pop ebp
    05750477 ret

    //value -= foo();
    057504AB mov eax,dword ptr ds:[015E440Ch] // STEP_B places (temp) to eax. eax now contains 0
    057504B0 mov dword ptr [ebp-40h],eax
    057504B3 call 05750038



    057504B8 mov dword ptr [ebp-44h],eax
    057504BB mov eax,dword ptr [ebp-40h]
    057504BE sub eax,dword ptr [ebp-44h] //STEP_C substract the return(-1) of call from the temp eax
    057504C1 mov dword ptr ds:[015E440Ch],eax // STEP_D moves eax (-1) value to our ds register to some memory location

    //Console.WriteLine(value);
    015E04C6 mov ecx,dword ptr ds:[015E440Ch] // Self explanatory; move our ds(-1) to ecx, and then print it out to the screen.
    015E04CC call 54CE8CBC


    So it is true that when writing value -= foo(), it generates code something like this:



    value = 0; // In the beginning STEP_A

    //... main
    var temp = value; //STEP_B
    temp -= foo(); // STEP_C
    value = temp; // STEP_D





    share|improve this answer



































      7



















      I think it has something to do with how it subtracts value on the assembly level, and that causes some inconsistency in the program. I don't know if it has something to do with static or not. But from my intuition this is what happens:



      Let's focus on value -= foo()



      1. The old value get saved (pushed to the stack)

      2. The foo() function returns 1

      3. Now, the value is -7 due to foo() operation

      4. HERE is the problem: The OLD value (which is the one that saved earlier, which is 0) subtracted with 1 and the result assigned to the current value.





      share|improve this answer























      • 5





        It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

        – Luaan
        Jul 25 at 8:04


















      5



















      value -= foo(); // value = value - foo();


      foo() will return 1.



      value is initially 0, so: 0 = 0 - 1.



      Now the value has -1.



      So the issue is with return 1.






      share|improve this answer























      • 3





        This answer ignores the fact that calling foo changes value.

        – Theraot
        Jul 24 at 10:25






      • 2





        @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

        – Eric Lippert
        Jul 25 at 19:14






      • 1





        @EricLippert that is true, however, it is still not good explaining it.

        – Theraot
        Jul 25 at 19:15






      • 1





        @Theraot i have explained only the core-concept, remaining upto you.

        – Arun Pandian k
        Aug 1 at 11:45


















      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      132



















      This problem is not about static; it's about how the subtraction works.



      value -= foo(); can be expanded to value = value - foo()



      The compiler will explain it into four steps:



      1. Load the value of value onto the stack.

      2. Call the method foo and put the result onto the stack.

      3. Do subtraction with these two values on the stack.

      4. Set the result back to value field.

      So the original value of value field is already loaded. Whatever you change value in the method foo, the result of the subtraction won't be affected.



      If you change the order to value = - foo() + value, then the value of value field will be loaded after foo is called. The result is -8; that's what you are expected to get.



      Thanks for Eliahu's comment.






      share|improve this answer























      • 14





        If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

        – Eliahu Aaron
        Jul 23 at 8:17






      • 7





        @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

        – Norman Gray
        Jul 24 at 8:43






      • 12





        @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

        – shingo
        Jul 24 at 9:13






      • 3





        @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

        – Luaan
        Jul 25 at 7:57







      • 6





        @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

        – Jeppe Stig Nielsen
        Jul 25 at 11:33















      132



















      This problem is not about static; it's about how the subtraction works.



      value -= foo(); can be expanded to value = value - foo()



      The compiler will explain it into four steps:



      1. Load the value of value onto the stack.

      2. Call the method foo and put the result onto the stack.

      3. Do subtraction with these two values on the stack.

      4. Set the result back to value field.

      So the original value of value field is already loaded. Whatever you change value in the method foo, the result of the subtraction won't be affected.



      If you change the order to value = - foo() + value, then the value of value field will be loaded after foo is called. The result is -8; that's what you are expected to get.



      Thanks for Eliahu's comment.






      share|improve this answer























      • 14





        If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

        – Eliahu Aaron
        Jul 23 at 8:17






      • 7





        @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

        – Norman Gray
        Jul 24 at 8:43






      • 12





        @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

        – shingo
        Jul 24 at 9:13






      • 3





        @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

        – Luaan
        Jul 25 at 7:57







      • 6





        @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

        – Jeppe Stig Nielsen
        Jul 25 at 11:33













      132














      132










      132










      This problem is not about static; it's about how the subtraction works.



      value -= foo(); can be expanded to value = value - foo()



      The compiler will explain it into four steps:



      1. Load the value of value onto the stack.

      2. Call the method foo and put the result onto the stack.

      3. Do subtraction with these two values on the stack.

      4. Set the result back to value field.

      So the original value of value field is already loaded. Whatever you change value in the method foo, the result of the subtraction won't be affected.



      If you change the order to value = - foo() + value, then the value of value field will be loaded after foo is called. The result is -8; that's what you are expected to get.



      Thanks for Eliahu's comment.






      share|improve this answer
















      This problem is not about static; it's about how the subtraction works.



      value -= foo(); can be expanded to value = value - foo()



      The compiler will explain it into four steps:



      1. Load the value of value onto the stack.

      2. Call the method foo and put the result onto the stack.

      3. Do subtraction with these two values on the stack.

      4. Set the result back to value field.

      So the original value of value field is already loaded. Whatever you change value in the method foo, the result of the subtraction won't be affected.



      If you change the order to value = - foo() + value, then the value of value field will be loaded after foo is called. The result is -8; that's what you are expected to get.



      Thanks for Eliahu's comment.







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited Jul 25 at 10:30









      Peter Mortensen

      14.6k19 gold badges89 silver badges118 bronze badges




      14.6k19 gold badges89 silver badges118 bronze badges










      answered Jul 23 at 8:02









      shingoshingo

      5,7434 gold badges10 silver badges25 bronze badges




      5,7434 gold badges10 silver badges25 bronze badges










      • 14





        If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

        – Eliahu Aaron
        Jul 23 at 8:17






      • 7





        @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

        – Norman Gray
        Jul 24 at 8:43






      • 12





        @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

        – shingo
        Jul 24 at 9:13






      • 3





        @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

        – Luaan
        Jul 25 at 7:57







      • 6





        @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

        – Jeppe Stig Nielsen
        Jul 25 at 11:33












      • 14





        If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

        – Eliahu Aaron
        Jul 23 at 8:17






      • 7





        @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

        – Norman Gray
        Jul 24 at 8:43






      • 12





        @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

        – shingo
        Jul 24 at 9:13






      • 3





        @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

        – Luaan
        Jul 25 at 7:57







      • 6





        @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

        – Jeppe Stig Nielsen
        Jul 25 at 11:33







      14




      14





      If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

      – Eliahu Aaron
      Jul 23 at 8:17





      If you change value = foo() - value to value = -foo() + value; in your last sentence you will get the 'expected' result -8

      – Eliahu Aaron
      Jul 23 at 8:17




      7




      7





      @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

      – Norman Gray
      Jul 24 at 8:43





      @EliahuAaron ...probably. The order of evaluation of operands is unspecified/unsequenced, so the compiler would be allowed to evaluate the two arguments in either order, or indeed in parallel. But your comment usefully emphasises that -= is a more complicated thing than may at first appear.

      – Norman Gray
      Jul 24 at 8:43




      12




      12





      @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

      – shingo
      Jul 24 at 9:13





      @NormanGray you remind me to search definition from specification, the link is c++ standard, and I find one for c#, it's from left to right.

      – shingo
      Jul 24 at 9:13




      3




      3





      @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

      – Luaan
      Jul 25 at 7:57






      @AlbertoSantini The addition part is. You don't get an analogue in Maths, since in an immutable world, the problem doesn't exist. It comes from mutability - depending on the order you do value and foo(), you get different results. The final addition, a + b, is commutative, but how you get a and b isn't.

      – Luaan
      Jul 25 at 7:57





      6




      6





      @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

      – Jeppe Stig Nielsen
      Jul 25 at 11:33





      @AlbertoSantini Because of side effects, it is not. A + B means first evaluate A (might cause side effects), keep the result, then evaluate B (side effects), finally add the results.

      – Jeppe Stig Nielsen
      Jul 25 at 11:33













      63



















      The statement



      value -= foo(); // short for value = value - foo();


      is equivalent to



      var temp = value; // 0
      var fooResult = foo(); // 1
      value = temp - fooResult; // -1


      That's why you are getting -1






      share|improve this answer























      • 11





        @Bahrom: It seems to work like you claim, but why?

        – Eliahu Aaron
        Jul 23 at 7:37







      • 16





        @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

        – Heinzi
        Jul 24 at 20:22















      63



















      The statement



      value -= foo(); // short for value = value - foo();


      is equivalent to



      var temp = value; // 0
      var fooResult = foo(); // 1
      value = temp - fooResult; // -1


      That's why you are getting -1






      share|improve this answer























      • 11





        @Bahrom: It seems to work like you claim, but why?

        – Eliahu Aaron
        Jul 23 at 7:37







      • 16





        @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

        – Heinzi
        Jul 24 at 20:22













      63














      63










      63










      The statement



      value -= foo(); // short for value = value - foo();


      is equivalent to



      var temp = value; // 0
      var fooResult = foo(); // 1
      value = temp - fooResult; // -1


      That's why you are getting -1






      share|improve this answer
















      The statement



      value -= foo(); // short for value = value - foo();


      is equivalent to



      var temp = value; // 0
      var fooResult = foo(); // 1
      value = temp - fooResult; // -1


      That's why you are getting -1







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited Jul 23 at 7:53

























      answered Jul 23 at 7:33









      BahromBahrom

      1,9721 gold badge10 silver badges17 bronze badges




      1,9721 gold badge10 silver badges17 bronze badges










      • 11





        @Bahrom: It seems to work like you claim, but why?

        – Eliahu Aaron
        Jul 23 at 7:37







      • 16





        @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

        – Heinzi
        Jul 24 at 20:22












      • 11





        @Bahrom: It seems to work like you claim, but why?

        – Eliahu Aaron
        Jul 23 at 7:37







      • 16





        @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

        – Heinzi
        Jul 24 at 20:22







      11




      11





      @Bahrom: It seems to work like you claim, but why?

      – Eliahu Aaron
      Jul 23 at 7:37






      @Bahrom: It seems to work like you claim, but why?

      – Eliahu Aaron
      Jul 23 at 7:37





      16




      16





      @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

      – Heinzi
      Jul 24 at 20:22





      @EliahuAaron: Because the C# spec says so. And why does the C# spec say so? Because (a) having a deterministic order of evaluation and (b) a -= b behaving like a = a - b (while evaluating a only once) are both widely considered to be good ideas. Would you have specified it differently? If yes, how, and why?

      – Heinzi
      Jul 24 at 20:22











      34



















      Just look at the generated CIL:



      .method private hidebysig static int32 foo() cil managed

      // Code size 19 (0x13)
      .maxstack 2
      .locals init ([0] int32 V_0)
      IL_0000: nop
      IL_0001: ldsfld int32 Program::'value'
      IL_0006: ldc.i4.7
      IL_0007: sub
      IL_0008: stsfld int32 Program::'value'
      IL_000d: ldc.i4.1
      IL_000e: stloc.0
      IL_000f: br.s IL_0011
      IL_0011: ldloc.0
      IL_0012: ret
      // end of method Program::foo



      • IL_0001: - Push the value of the static field on the stack. s:[value(0)]


      • IL_0006: - Push 7 onto the stack. s:[7, value(0)]


      • IL_0007: - Subtracts value2 (7) from value1 (0), returning a new value (-7).


      • IL_0008: - Replaces the value of the static field with val (value = -7).


      • IL_000d: - Push 1 onto the stack. s:[1, 7, value(-7)]


      • IL_000e: - Pop a value from stack into local variable 0. (lv = 1)


      • IL_0011: - Load local variable 0 onto stack. s:[lv(1), 7, value(-7)]


      • IL_0012: - Return (lv(1))

      And the Main method:



      .method private hidebysig static void Main(string[] args) cil managed

      .entrypoint
      // Code size 29 (0x1d)
      .maxstack 8
      IL_0000: nop
      IL_0001: ldsfld int32 Program::'value'
      IL_0006: call int32 Program::foo()
      IL_000b: sub
      IL_000c: stsfld int32 Program::'value'
      IL_0011: ldsfld int32 Program::'value'
      IL_0016: call void [mscorlib]System.Console::WriteLine(int32)
      IL_001b: nop
      IL_001c: ret
      // end of method Program::Main



      • IL_0001: - pushes value onto stack (which is 0)


      • IL_0006: - calls foo (which will return 1)


      • IL_000b: - subtract values: value2(1) from value1(0) (value(0) - value(1) = -1).

      So the result is -1.






      share|improve this answer
































        34



















        Just look at the generated CIL:



        .method private hidebysig static int32 foo() cil managed

        // Code size 19 (0x13)
        .maxstack 2
        .locals init ([0] int32 V_0)
        IL_0000: nop
        IL_0001: ldsfld int32 Program::'value'
        IL_0006: ldc.i4.7
        IL_0007: sub
        IL_0008: stsfld int32 Program::'value'
        IL_000d: ldc.i4.1
        IL_000e: stloc.0
        IL_000f: br.s IL_0011
        IL_0011: ldloc.0
        IL_0012: ret
        // end of method Program::foo



        • IL_0001: - Push the value of the static field on the stack. s:[value(0)]


        • IL_0006: - Push 7 onto the stack. s:[7, value(0)]


        • IL_0007: - Subtracts value2 (7) from value1 (0), returning a new value (-7).


        • IL_0008: - Replaces the value of the static field with val (value = -7).


        • IL_000d: - Push 1 onto the stack. s:[1, 7, value(-7)]


        • IL_000e: - Pop a value from stack into local variable 0. (lv = 1)


        • IL_0011: - Load local variable 0 onto stack. s:[lv(1), 7, value(-7)]


        • IL_0012: - Return (lv(1))

        And the Main method:



        .method private hidebysig static void Main(string[] args) cil managed

        .entrypoint
        // Code size 29 (0x1d)
        .maxstack 8
        IL_0000: nop
        IL_0001: ldsfld int32 Program::'value'
        IL_0006: call int32 Program::foo()
        IL_000b: sub
        IL_000c: stsfld int32 Program::'value'
        IL_0011: ldsfld int32 Program::'value'
        IL_0016: call void [mscorlib]System.Console::WriteLine(int32)
        IL_001b: nop
        IL_001c: ret
        // end of method Program::Main



        • IL_0001: - pushes value onto stack (which is 0)


        • IL_0006: - calls foo (which will return 1)


        • IL_000b: - subtract values: value2(1) from value1(0) (value(0) - value(1) = -1).

        So the result is -1.






        share|improve this answer






























          34














          34










          34










          Just look at the generated CIL:



          .method private hidebysig static int32 foo() cil managed

          // Code size 19 (0x13)
          .maxstack 2
          .locals init ([0] int32 V_0)
          IL_0000: nop
          IL_0001: ldsfld int32 Program::'value'
          IL_0006: ldc.i4.7
          IL_0007: sub
          IL_0008: stsfld int32 Program::'value'
          IL_000d: ldc.i4.1
          IL_000e: stloc.0
          IL_000f: br.s IL_0011
          IL_0011: ldloc.0
          IL_0012: ret
          // end of method Program::foo



          • IL_0001: - Push the value of the static field on the stack. s:[value(0)]


          • IL_0006: - Push 7 onto the stack. s:[7, value(0)]


          • IL_0007: - Subtracts value2 (7) from value1 (0), returning a new value (-7).


          • IL_0008: - Replaces the value of the static field with val (value = -7).


          • IL_000d: - Push 1 onto the stack. s:[1, 7, value(-7)]


          • IL_000e: - Pop a value from stack into local variable 0. (lv = 1)


          • IL_0011: - Load local variable 0 onto stack. s:[lv(1), 7, value(-7)]


          • IL_0012: - Return (lv(1))

          And the Main method:



          .method private hidebysig static void Main(string[] args) cil managed

          .entrypoint
          // Code size 29 (0x1d)
          .maxstack 8
          IL_0000: nop
          IL_0001: ldsfld int32 Program::'value'
          IL_0006: call int32 Program::foo()
          IL_000b: sub
          IL_000c: stsfld int32 Program::'value'
          IL_0011: ldsfld int32 Program::'value'
          IL_0016: call void [mscorlib]System.Console::WriteLine(int32)
          IL_001b: nop
          IL_001c: ret
          // end of method Program::Main



          • IL_0001: - pushes value onto stack (which is 0)


          • IL_0006: - calls foo (which will return 1)


          • IL_000b: - subtract values: value2(1) from value1(0) (value(0) - value(1) = -1).

          So the result is -1.






          share|improve this answer
















          Just look at the generated CIL:



          .method private hidebysig static int32 foo() cil managed

          // Code size 19 (0x13)
          .maxstack 2
          .locals init ([0] int32 V_0)
          IL_0000: nop
          IL_0001: ldsfld int32 Program::'value'
          IL_0006: ldc.i4.7
          IL_0007: sub
          IL_0008: stsfld int32 Program::'value'
          IL_000d: ldc.i4.1
          IL_000e: stloc.0
          IL_000f: br.s IL_0011
          IL_0011: ldloc.0
          IL_0012: ret
          // end of method Program::foo



          • IL_0001: - Push the value of the static field on the stack. s:[value(0)]


          • IL_0006: - Push 7 onto the stack. s:[7, value(0)]


          • IL_0007: - Subtracts value2 (7) from value1 (0), returning a new value (-7).


          • IL_0008: - Replaces the value of the static field with val (value = -7).


          • IL_000d: - Push 1 onto the stack. s:[1, 7, value(-7)]


          • IL_000e: - Pop a value from stack into local variable 0. (lv = 1)


          • IL_0011: - Load local variable 0 onto stack. s:[lv(1), 7, value(-7)]


          • IL_0012: - Return (lv(1))

          And the Main method:



          .method private hidebysig static void Main(string[] args) cil managed

          .entrypoint
          // Code size 29 (0x1d)
          .maxstack 8
          IL_0000: nop
          IL_0001: ldsfld int32 Program::'value'
          IL_0006: call int32 Program::foo()
          IL_000b: sub
          IL_000c: stsfld int32 Program::'value'
          IL_0011: ldsfld int32 Program::'value'
          IL_0016: call void [mscorlib]System.Console::WriteLine(int32)
          IL_001b: nop
          IL_001c: ret
          // end of method Program::Main



          • IL_0001: - pushes value onto stack (which is 0)


          • IL_0006: - calls foo (which will return 1)


          • IL_000b: - subtract values: value2(1) from value1(0) (value(0) - value(1) = -1).

          So the result is -1.







          share|improve this answer















          share|improve this answer




          share|improve this answer








          edited Jul 25 at 10:39









          Peter Mortensen

          14.6k19 gold badges89 silver badges118 bronze badges




          14.6k19 gold badges89 silver badges118 bronze badges










          answered Jul 23 at 8:18









          SᴇMSᴇM

          5,6572 gold badges18 silver badges34 bronze badges




          5,6572 gold badges18 silver badges34 bronze badges
























              18



















              You can use menu DebugWindowsDisassembly and check what goes on in the background:



              I commented the most interesting parts.



               //static int value = 0;
              05750449 mov ebp,esp
              0575044B push edi
              0575044C push esi
              0575044D push ebx
              0575044E sub esp,2Ch
              05750451 xor edx,edx
              05750453 mov dword ptr [ebp-10h],edx
              05750456 mov dword ptr [ebp-1Ch],edx
              05750459 cmp dword ptr ds:[15E42D8h],0
              05750460 je 05750467
              05750462 call 55884370
              05750467 xor edx,edx
              05750469 mov dword ptr ds:[15E440Ch],edx // STEP_A place 0 in ds register
              somewhere
              0575046F nop
              05750470 lea esp,[ebp-0Ch]
              05750473 pop ebx
              05750474 pop esi
              05750475 pop edi
              05750476 pop ebp
              05750477 ret

              //value -= foo();
              057504AB mov eax,dword ptr ds:[015E440Ch] // STEP_B places (temp) to eax. eax now contains 0
              057504B0 mov dword ptr [ebp-40h],eax
              057504B3 call 05750038



              057504B8 mov dword ptr [ebp-44h],eax
              057504BB mov eax,dword ptr [ebp-40h]
              057504BE sub eax,dword ptr [ebp-44h] //STEP_C substract the return(-1) of call from the temp eax
              057504C1 mov dword ptr ds:[015E440Ch],eax // STEP_D moves eax (-1) value to our ds register to some memory location

              //Console.WriteLine(value);
              015E04C6 mov ecx,dword ptr ds:[015E440Ch] // Self explanatory; move our ds(-1) to ecx, and then print it out to the screen.
              015E04CC call 54CE8CBC


              So it is true that when writing value -= foo(), it generates code something like this:



              value = 0; // In the beginning STEP_A

              //... main
              var temp = value; //STEP_B
              temp -= foo(); // STEP_C
              value = temp; // STEP_D





              share|improve this answer
































                18



















                You can use menu DebugWindowsDisassembly and check what goes on in the background:



                I commented the most interesting parts.



                 //static int value = 0;
                05750449 mov ebp,esp
                0575044B push edi
                0575044C push esi
                0575044D push ebx
                0575044E sub esp,2Ch
                05750451 xor edx,edx
                05750453 mov dword ptr [ebp-10h],edx
                05750456 mov dword ptr [ebp-1Ch],edx
                05750459 cmp dword ptr ds:[15E42D8h],0
                05750460 je 05750467
                05750462 call 55884370
                05750467 xor edx,edx
                05750469 mov dword ptr ds:[15E440Ch],edx // STEP_A place 0 in ds register
                somewhere
                0575046F nop
                05750470 lea esp,[ebp-0Ch]
                05750473 pop ebx
                05750474 pop esi
                05750475 pop edi
                05750476 pop ebp
                05750477 ret

                //value -= foo();
                057504AB mov eax,dword ptr ds:[015E440Ch] // STEP_B places (temp) to eax. eax now contains 0
                057504B0 mov dword ptr [ebp-40h],eax
                057504B3 call 05750038



                057504B8 mov dword ptr [ebp-44h],eax
                057504BB mov eax,dword ptr [ebp-40h]
                057504BE sub eax,dword ptr [ebp-44h] //STEP_C substract the return(-1) of call from the temp eax
                057504C1 mov dword ptr ds:[015E440Ch],eax // STEP_D moves eax (-1) value to our ds register to some memory location

                //Console.WriteLine(value);
                015E04C6 mov ecx,dword ptr ds:[015E440Ch] // Self explanatory; move our ds(-1) to ecx, and then print it out to the screen.
                015E04CC call 54CE8CBC


                So it is true that when writing value -= foo(), it generates code something like this:



                value = 0; // In the beginning STEP_A

                //... main
                var temp = value; //STEP_B
                temp -= foo(); // STEP_C
                value = temp; // STEP_D





                share|improve this answer






























                  18














                  18










                  18










                  You can use menu DebugWindowsDisassembly and check what goes on in the background:



                  I commented the most interesting parts.



                   //static int value = 0;
                  05750449 mov ebp,esp
                  0575044B push edi
                  0575044C push esi
                  0575044D push ebx
                  0575044E sub esp,2Ch
                  05750451 xor edx,edx
                  05750453 mov dword ptr [ebp-10h],edx
                  05750456 mov dword ptr [ebp-1Ch],edx
                  05750459 cmp dword ptr ds:[15E42D8h],0
                  05750460 je 05750467
                  05750462 call 55884370
                  05750467 xor edx,edx
                  05750469 mov dword ptr ds:[15E440Ch],edx // STEP_A place 0 in ds register
                  somewhere
                  0575046F nop
                  05750470 lea esp,[ebp-0Ch]
                  05750473 pop ebx
                  05750474 pop esi
                  05750475 pop edi
                  05750476 pop ebp
                  05750477 ret

                  //value -= foo();
                  057504AB mov eax,dword ptr ds:[015E440Ch] // STEP_B places (temp) to eax. eax now contains 0
                  057504B0 mov dword ptr [ebp-40h],eax
                  057504B3 call 05750038



                  057504B8 mov dword ptr [ebp-44h],eax
                  057504BB mov eax,dword ptr [ebp-40h]
                  057504BE sub eax,dword ptr [ebp-44h] //STEP_C substract the return(-1) of call from the temp eax
                  057504C1 mov dword ptr ds:[015E440Ch],eax // STEP_D moves eax (-1) value to our ds register to some memory location

                  //Console.WriteLine(value);
                  015E04C6 mov ecx,dword ptr ds:[015E440Ch] // Self explanatory; move our ds(-1) to ecx, and then print it out to the screen.
                  015E04CC call 54CE8CBC


                  So it is true that when writing value -= foo(), it generates code something like this:



                  value = 0; // In the beginning STEP_A

                  //... main
                  var temp = value; //STEP_B
                  temp -= foo(); // STEP_C
                  value = temp; // STEP_D





                  share|improve this answer
















                  You can use menu DebugWindowsDisassembly and check what goes on in the background:



                  I commented the most interesting parts.



                   //static int value = 0;
                  05750449 mov ebp,esp
                  0575044B push edi
                  0575044C push esi
                  0575044D push ebx
                  0575044E sub esp,2Ch
                  05750451 xor edx,edx
                  05750453 mov dword ptr [ebp-10h],edx
                  05750456 mov dword ptr [ebp-1Ch],edx
                  05750459 cmp dword ptr ds:[15E42D8h],0
                  05750460 je 05750467
                  05750462 call 55884370
                  05750467 xor edx,edx
                  05750469 mov dword ptr ds:[15E440Ch],edx // STEP_A place 0 in ds register
                  somewhere
                  0575046F nop
                  05750470 lea esp,[ebp-0Ch]
                  05750473 pop ebx
                  05750474 pop esi
                  05750475 pop edi
                  05750476 pop ebp
                  05750477 ret

                  //value -= foo();
                  057504AB mov eax,dword ptr ds:[015E440Ch] // STEP_B places (temp) to eax. eax now contains 0
                  057504B0 mov dword ptr [ebp-40h],eax
                  057504B3 call 05750038



                  057504B8 mov dword ptr [ebp-44h],eax
                  057504BB mov eax,dword ptr [ebp-40h]
                  057504BE sub eax,dword ptr [ebp-44h] //STEP_C substract the return(-1) of call from the temp eax
                  057504C1 mov dword ptr ds:[015E440Ch],eax // STEP_D moves eax (-1) value to our ds register to some memory location

                  //Console.WriteLine(value);
                  015E04C6 mov ecx,dword ptr ds:[015E440Ch] // Self explanatory; move our ds(-1) to ecx, and then print it out to the screen.
                  015E04CC call 54CE8CBC


                  So it is true that when writing value -= foo(), it generates code something like this:



                  value = 0; // In the beginning STEP_A

                  //... main
                  var temp = value; //STEP_B
                  temp -= foo(); // STEP_C
                  value = temp; // STEP_D






                  share|improve this answer















                  share|improve this answer




                  share|improve this answer








                  edited Jul 25 at 10:45









                  Peter Mortensen

                  14.6k19 gold badges89 silver badges118 bronze badges




                  14.6k19 gold badges89 silver badges118 bronze badges










                  answered Jul 23 at 8:45









                  kovirolikoviroli

                  1,2321 gold badge8 silver badges21 bronze badges




                  1,2321 gold badge8 silver badges21 bronze badges
























                      7



















                      I think it has something to do with how it subtracts value on the assembly level, and that causes some inconsistency in the program. I don't know if it has something to do with static or not. But from my intuition this is what happens:



                      Let's focus on value -= foo()



                      1. The old value get saved (pushed to the stack)

                      2. The foo() function returns 1

                      3. Now, the value is -7 due to foo() operation

                      4. HERE is the problem: The OLD value (which is the one that saved earlier, which is 0) subtracted with 1 and the result assigned to the current value.





                      share|improve this answer























                      • 5





                        It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                        – Luaan
                        Jul 25 at 8:04















                      7



















                      I think it has something to do with how it subtracts value on the assembly level, and that causes some inconsistency in the program. I don't know if it has something to do with static or not. But from my intuition this is what happens:



                      Let's focus on value -= foo()



                      1. The old value get saved (pushed to the stack)

                      2. The foo() function returns 1

                      3. Now, the value is -7 due to foo() operation

                      4. HERE is the problem: The OLD value (which is the one that saved earlier, which is 0) subtracted with 1 and the result assigned to the current value.





                      share|improve this answer























                      • 5





                        It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                        – Luaan
                        Jul 25 at 8:04













                      7














                      7










                      7










                      I think it has something to do with how it subtracts value on the assembly level, and that causes some inconsistency in the program. I don't know if it has something to do with static or not. But from my intuition this is what happens:



                      Let's focus on value -= foo()



                      1. The old value get saved (pushed to the stack)

                      2. The foo() function returns 1

                      3. Now, the value is -7 due to foo() operation

                      4. HERE is the problem: The OLD value (which is the one that saved earlier, which is 0) subtracted with 1 and the result assigned to the current value.





                      share|improve this answer
















                      I think it has something to do with how it subtracts value on the assembly level, and that causes some inconsistency in the program. I don't know if it has something to do with static or not. But from my intuition this is what happens:



                      Let's focus on value -= foo()



                      1. The old value get saved (pushed to the stack)

                      2. The foo() function returns 1

                      3. Now, the value is -7 due to foo() operation

                      4. HERE is the problem: The OLD value (which is the one that saved earlier, which is 0) subtracted with 1 and the result assigned to the current value.






                      share|improve this answer















                      share|improve this answer




                      share|improve this answer








                      edited Jul 25 at 10:46









                      Peter Mortensen

                      14.6k19 gold badges89 silver badges118 bronze badges




                      14.6k19 gold badges89 silver badges118 bronze badges










                      answered Jul 23 at 9:02









                      molmol

                      904 bronze badges




                      904 bronze badges










                      • 5





                        It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                        – Luaan
                        Jul 25 at 8:04












                      • 5





                        It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                        – Luaan
                        Jul 25 at 8:04







                      5




                      5





                      It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                      – Luaan
                      Jul 25 at 8:04





                      It's not just an accident - the C# specification specifically defines the order of execution in such a case - the compiler is not allowed to produce code that would output anything else than -1, unlike in C.

                      – Luaan
                      Jul 25 at 8:04











                      5



















                      value -= foo(); // value = value - foo();


                      foo() will return 1.



                      value is initially 0, so: 0 = 0 - 1.



                      Now the value has -1.



                      So the issue is with return 1.






                      share|improve this answer























                      • 3





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        Jul 24 at 10:25






                      • 2





                        @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                        – Eric Lippert
                        Jul 25 at 19:14






                      • 1





                        @EricLippert that is true, however, it is still not good explaining it.

                        – Theraot
                        Jul 25 at 19:15






                      • 1





                        @Theraot i have explained only the core-concept, remaining upto you.

                        – Arun Pandian k
                        Aug 1 at 11:45















                      5



















                      value -= foo(); // value = value - foo();


                      foo() will return 1.



                      value is initially 0, so: 0 = 0 - 1.



                      Now the value has -1.



                      So the issue is with return 1.






                      share|improve this answer























                      • 3





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        Jul 24 at 10:25






                      • 2





                        @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                        – Eric Lippert
                        Jul 25 at 19:14






                      • 1





                        @EricLippert that is true, however, it is still not good explaining it.

                        – Theraot
                        Jul 25 at 19:15






                      • 1





                        @Theraot i have explained only the core-concept, remaining upto you.

                        – Arun Pandian k
                        Aug 1 at 11:45













                      5














                      5










                      5










                      value -= foo(); // value = value - foo();


                      foo() will return 1.



                      value is initially 0, so: 0 = 0 - 1.



                      Now the value has -1.



                      So the issue is with return 1.






                      share|improve this answer
















                      value -= foo(); // value = value - foo();


                      foo() will return 1.



                      value is initially 0, so: 0 = 0 - 1.



                      Now the value has -1.



                      So the issue is with return 1.







                      share|improve this answer















                      share|improve this answer




                      share|improve this answer








                      edited Jul 25 at 10:31









                      Peter Mortensen

                      14.6k19 gold badges89 silver badges118 bronze badges




                      14.6k19 gold badges89 silver badges118 bronze badges










                      answered Jul 23 at 8:03









                      Arun Pandian kArun Pandian k

                      1058 bronze badges




                      1058 bronze badges










                      • 3





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        Jul 24 at 10:25






                      • 2





                        @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                        – Eric Lippert
                        Jul 25 at 19:14






                      • 1





                        @EricLippert that is true, however, it is still not good explaining it.

                        – Theraot
                        Jul 25 at 19:15






                      • 1





                        @Theraot i have explained only the core-concept, remaining upto you.

                        – Arun Pandian k
                        Aug 1 at 11:45












                      • 3





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        Jul 24 at 10:25






                      • 2





                        @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                        – Eric Lippert
                        Jul 25 at 19:14






                      • 1





                        @EricLippert that is true, however, it is still not good explaining it.

                        – Theraot
                        Jul 25 at 19:15






                      • 1





                        @Theraot i have explained only the core-concept, remaining upto you.

                        – Arun Pandian k
                        Aug 1 at 11:45







                      3




                      3





                      This answer ignores the fact that calling foo changes value.

                      – Theraot
                      Jul 24 at 10:25





                      This answer ignores the fact that calling foo changes value.

                      – Theraot
                      Jul 24 at 10:25




                      2




                      2





                      @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                      – Eric Lippert
                      Jul 25 at 19:14





                      @Theraot: This answer is correct; the fact that foo changes value is irrelevant. Regardless of what values foo changes, the fact is that subtraction in C# proceeds from left-to-right.

                      – Eric Lippert
                      Jul 25 at 19:14




                      1




                      1





                      @EricLippert that is true, however, it is still not good explaining it.

                      – Theraot
                      Jul 25 at 19:15





                      @EricLippert that is true, however, it is still not good explaining it.

                      – Theraot
                      Jul 25 at 19:15




                      1




                      1





                      @Theraot i have explained only the core-concept, remaining upto you.

                      – Arun Pandian k
                      Aug 1 at 11:45





                      @Theraot i have explained only the core-concept, remaining upto you.

                      – Arun Pandian k
                      Aug 1 at 11:45



                      Popular posts from this blog

                      Tamil (spriik) Luke uk diar | Nawigatjuun

                      Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

                      Where does the image of a data connector as a sharp metal spike originate from?Where does the concept of infected people turning into zombies only after death originate from?Where does the motif of a reanimated human head originate?Where did the notion that Dragons could speak originate?Where does the archetypal image of the 'Grey' alien come from?Where did the suffix '-Man' originate?Where does the notion of being injured or killed by an illusion originate?Where did the term “sophont” originate?Where does the trope of magic spells being driven by advanced technology originate from?Where did the term “the living impaired” originate?