'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

Why are angular mometum and angular velocity not necessarily parallel, but linear momentum and linear velocity are always parallel?

Problem loading expl3 in plain TeX

401(k) investment after being fired. Do I own it?

Why did modems have speakers?

How do I run a game when my PCs have different approaches to combat?

Examples of solving for unknowns using equivalence relations that are not equality, inequality, or boolean truth?

"I you already know": is this proper English?

Why did NASA use U.S customary units?

Keeping an "hot eyeball planet" wet

Why are so many countries still in the Commonwealth?

Other than a swing wing, what types of variable geometry have flown?

How to handle aversion that derives from perceiving arrogance?

Why keep the bed heated after initial layer(s) with PLA (or PETG)?

Where is this photo of a group of hikers taken? Is it really in the Ural?

How can I stop myself from micromanaging other PCs' actions?

How may I shorten this shell script?

How to sort and filter a constantly changing list of data?

Spoken encryption

Why is the return type for ftell not fpos_t?

Where to place an artificial gland in the human body?

What is the meaning of "a thinly disguised price"?

Character Frequency in a String

Which creatures count as green creatures?

Why are off grid solar setups only 12, 24, 48 VDC?



'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;








59
















This question already has an answer here:



  • Behaviour and Order of evaluation in C# [duplicate]

    2 answers



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















marked as duplicate by GSerg, dandan78, Silviu Burcea, TnTinMn, TheGeneral 17 mins ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • 8





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

    – TvanB
    2 days ago






  • 46





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    2 days ago






  • 7





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

    – EmerG
    2 days ago







  • 13





    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
    2 days ago







  • 2





    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
    yesterday

















59
















This question already has an answer here:



  • Behaviour and Order of evaluation in C# [duplicate]

    2 answers



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















marked as duplicate by GSerg, dandan78, Silviu Burcea, TnTinMn, TheGeneral 17 mins ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • 8





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

    – TvanB
    2 days ago






  • 46





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    2 days ago






  • 7





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

    – EmerG
    2 days ago







  • 13





    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
    2 days ago







  • 2





    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
    yesterday













59












59








59


9







This question already has an answer here:



  • Behaviour and Order of evaluation in C# [duplicate]

    2 answers



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

















This question already has an answer here:



  • Behaviour and Order of evaluation in C# [duplicate]

    2 answers



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 an answer here:



  • 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 1 hour ago









J. Antonio Perez

5,94811 silver badges26 bronze badges




5,94811 silver badges26 bronze badges










asked 2 days ago









EmerGEmerG

3745 silver badges10 bronze badges




3745 silver badges10 bronze badges




marked as duplicate by GSerg, dandan78, Silviu Burcea, TnTinMn, TheGeneral 17 mins ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by GSerg, dandan78, Silviu Burcea, TnTinMn, TheGeneral 17 mins ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









  • 8





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

    – TvanB
    2 days ago






  • 46





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    2 days ago






  • 7





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

    – EmerG
    2 days ago







  • 13





    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
    2 days ago







  • 2





    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
    yesterday












  • 8





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

    – TvanB
    2 days ago






  • 46





    FYI, this has nothing to do with static.

    – Ahmed Abdelhameed
    2 days ago






  • 7





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

    – EmerG
    2 days ago







  • 13





    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
    2 days ago







  • 2





    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
    yesterday







8




8





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

– TvanB
2 days ago





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

– TvanB
2 days ago




46




46





FYI, this has nothing to do with static.

– Ahmed Abdelhameed
2 days ago





FYI, this has nothing to do with static.

– Ahmed Abdelhameed
2 days ago




7




7





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

– EmerG
2 days ago






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

– EmerG
2 days ago





13




13





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
2 days ago






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
2 days ago





2




2





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
yesterday





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
yesterday












6 Answers
6






active

oldest

votes


















108














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




















  • 9





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

    – Eliahu Aaron
    2 days ago






  • 4





    @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
    yesterday






  • 10





    @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
    yesterday






  • 1





    Wait, does this mean that addition is not commutative?

    – Alberto Santini
    17 hours ago






  • 3





    @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
    11 hours ago


















50














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




















  • 9





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

    – Eliahu Aaron
    2 days ago







  • 12





    @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
    yesterday


















22














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
































    8














    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
































      1














      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




















      • 3





        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
        15 hours ago


















      -1














      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




















      • 2





        This answer ignores the fact that calling foo changes value.

        – Theraot
        yesterday






      • 1





        @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
        4 hours ago











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

        – Theraot
        4 hours ago



















      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      108














      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




















      • 9





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

        – Eliahu Aaron
        2 days ago






      • 4





        @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
        yesterday






      • 10





        @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
        yesterday






      • 1





        Wait, does this mean that addition is not commutative?

        – Alberto Santini
        17 hours ago






      • 3





        @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
        11 hours ago















      108














      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




















      • 9





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

        – Eliahu Aaron
        2 days ago






      • 4





        @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
        yesterday






      • 10





        @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
        yesterday






      • 1





        Wait, does this mean that addition is not commutative?

        – Alberto Santini
        17 hours ago






      • 3





        @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
        11 hours ago













      108












      108








      108







      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 12 hours ago









      Peter Mortensen

      14.3k19 gold badges88 silver badges116 bronze badges




      14.3k19 gold badges88 silver badges116 bronze badges










      answered 2 days ago









      shingoshingo

      5,0134 gold badges10 silver badges25 bronze badges




      5,0134 gold badges10 silver badges25 bronze badges







      • 9





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

        – Eliahu Aaron
        2 days ago






      • 4





        @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
        yesterday






      • 10





        @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
        yesterday






      • 1





        Wait, does this mean that addition is not commutative?

        – Alberto Santini
        17 hours ago






      • 3





        @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
        11 hours ago












      • 9





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

        – Eliahu Aaron
        2 days ago






      • 4





        @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
        yesterday






      • 10





        @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
        yesterday






      • 1





        Wait, does this mean that addition is not commutative?

        – Alberto Santini
        17 hours ago






      • 3





        @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
        11 hours ago







      9




      9





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

      – Eliahu Aaron
      2 days ago





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

      – Eliahu Aaron
      2 days ago




      4




      4





      @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
      yesterday





      @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
      yesterday




      10




      10





      @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
      yesterday





      @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
      yesterday




      1




      1





      Wait, does this mean that addition is not commutative?

      – Alberto Santini
      17 hours ago





      Wait, does this mean that addition is not commutative?

      – Alberto Santini
      17 hours ago




      3




      3





      @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
      11 hours ago





      @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
      11 hours ago













      50














      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




















      • 9





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

        – Eliahu Aaron
        2 days ago







      • 12





        @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
        yesterday















      50














      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




















      • 9





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

        – Eliahu Aaron
        2 days ago







      • 12





        @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
        yesterday













      50












      50








      50







      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 2 days ago

























      answered 2 days ago









      BahromBahrom

      1,7559 silver badges17 bronze badges




      1,7559 silver badges17 bronze badges







      • 9





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

        – Eliahu Aaron
        2 days ago







      • 12





        @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
        yesterday












      • 9





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

        – Eliahu Aaron
        2 days ago







      • 12





        @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
        yesterday







      9




      9





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

      – Eliahu Aaron
      2 days ago






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

      – Eliahu Aaron
      2 days ago





      12




      12





      @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
      yesterday





      @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
      yesterday











      22














      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





























        22














        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



























          22












          22








          22







          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 12 hours ago









          Peter Mortensen

          14.3k19 gold badges88 silver badges116 bronze badges




          14.3k19 gold badges88 silver badges116 bronze badges










          answered 2 days ago









          SᴇMSᴇM

          5,4262 gold badges16 silver badges32 bronze badges




          5,4262 gold badges16 silver badges32 bronze badges





















              8














              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





























                8














                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



























                  8












                  8








                  8







                  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 12 hours ago









                  Peter Mortensen

                  14.3k19 gold badges88 silver badges116 bronze badges




                  14.3k19 gold badges88 silver badges116 bronze badges










                  answered 2 days ago









                  kovirolikoviroli

                  8365 silver badges16 bronze badges




                  8365 silver badges16 bronze badges





















                      1














                      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




















                      • 3





                        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
                        15 hours ago















                      1














                      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




















                      • 3





                        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
                        15 hours ago













                      1












                      1








                      1







                      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 12 hours ago









                      Peter Mortensen

                      14.3k19 gold badges88 silver badges116 bronze badges




                      14.3k19 gold badges88 silver badges116 bronze badges










                      answered 2 days ago









                      molmol

                      303 bronze badges




                      303 bronze badges







                      • 3





                        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
                        15 hours ago












                      • 3





                        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
                        15 hours ago







                      3




                      3





                      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
                      15 hours ago





                      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
                      15 hours ago











                      -1














                      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




















                      • 2





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        yesterday






                      • 1





                        @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
                        4 hours ago











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

                        – Theraot
                        4 hours ago















                      -1














                      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




















                      • 2





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        yesterday






                      • 1





                        @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
                        4 hours ago











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

                        – Theraot
                        4 hours ago













                      -1












                      -1








                      -1







                      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 12 hours ago









                      Peter Mortensen

                      14.3k19 gold badges88 silver badges116 bronze badges




                      14.3k19 gold badges88 silver badges116 bronze badges










                      answered 2 days ago









                      Arun Pandian kArun Pandian k

                      93 bronze badges




                      93 bronze badges







                      • 2





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        yesterday






                      • 1





                        @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
                        4 hours ago











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

                        – Theraot
                        4 hours ago












                      • 2





                        This answer ignores the fact that calling foo changes value.

                        – Theraot
                        yesterday






                      • 1





                        @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
                        4 hours ago











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

                        – Theraot
                        4 hours ago







                      2




                      2





                      This answer ignores the fact that calling foo changes value.

                      – Theraot
                      yesterday





                      This answer ignores the fact that calling foo changes value.

                      – Theraot
                      yesterday




                      1




                      1





                      @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
                      4 hours ago





                      @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
                      4 hours ago













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

                      – Theraot
                      4 hours ago





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

                      – Theraot
                      4 hours ago



                      Popular posts from this blog

                      Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                      Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                      François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480