Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Strange IL code from simple C# expression

Strange IL code from simple C# expression

Scheduled Pinned Locked Moved C#
questioncsharpdotnet
29 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Dave Kreskowiak

    After doing some digging, the evaluation rules are slightly different between the C++ language specifications and the C# specs. It's not a bug as far the specifications describes the process. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

    W Offline
    W Offline
    Wjousts
    wrote on last edited by
    #17

    No, I think it is a bug, evaulation rules or not. It's very easy to miss (and I did at first) but the prefix/postfix thing is irrelevant: int i = 5; i = i++; versus int i = 5; i = ++i; Should both end up with i = 6. i++ is the same as i = i + 1 (so is ++i) so really the both code snippets should become int i = 5; i = i; i = i + 1; and int i = 5; i = i + 1; i = i; It shouldn't matter if you do i = i first or i = i + 1 first the result should still be six. As somebody else pointed out, it you do j = i++ then look at the value of j then the prefix/postfix part matters, but because you are putting the result back in to i it should be six either way.

    D 1 Reply Last reply
    0
    • W Wjousts

      No, I think it is a bug, evaulation rules or not. It's very easy to miss (and I did at first) but the prefix/postfix thing is irrelevant: int i = 5; i = i++; versus int i = 5; i = ++i; Should both end up with i = 6. i++ is the same as i = i + 1 (so is ++i) so really the both code snippets should become int i = 5; i = i; i = i + 1; and int i = 5; i = i + 1; i = i; It shouldn't matter if you do i = i first or i = i + 1 first the result should still be six. As somebody else pointed out, it you do j = i++ then look at the value of j then the prefix/postfix part matters, but because you are putting the result back in to i it should be six either way.

      D Offline
      D Offline
      Dave Kreskowiak
      wrote on last edited by
      #18

      According the doc's I read in the specifications, the result your seeing is the expected result of the expression. C# in 2002, 2003, and 2005 do the exact same thing. The specifications between versions didn't change. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

      W 1 Reply Last reply
      0
      • D Dave Kreskowiak

        According the doc's I read in the specifications, the result your seeing is the expected result of the expression. C# in 2002, 2003, and 2005 do the exact same thing. The specifications between versions didn't change. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

        W Offline
        W Offline
        Wjousts
        wrote on last edited by
        #19

        The specifications concerning the behavor of postfix and prefix increment aren't relavent. The result should be 6 either way! i = i++; i gets assigned 5 and then i gets incremented. Therefore i = 6.

        D D 2 Replies Last reply
        0
        • W Wjousts

          The specifications concerning the behavor of postfix and prefix increment aren't relavent. The result should be 6 either way! i = i++; i gets assigned 5 and then i gets incremented. Therefore i = 6.

          D Offline
          D Offline
          Daniel Grunwald
          wrote on last edited by
          #20

          Wjousts wrote: i gets assigned 5 and then i gets incremented. Therefore i = 6. That's not the normal execution order. The real execution order (in C#) is: Read value of i Increment i Assign old value of i to i Why should the "++" wait until after the assignment? It directly binds to "i": AssignmentExpression: Left=i Op=Assign Right=[UnaryExpression: Op=PostIncrement Expr=i] It behaves differently in C++ because C++ has very strange rules for execution order.

          1 Reply Last reply
          0
          • W Wjousts

            The specifications concerning the behavor of postfix and prefix increment aren't relavent. The result should be 6 either way! i = i++; i gets assigned 5 and then i gets incremented. Therefore i = 6.

            D Offline
            D Offline
            Dave Kreskowiak
            wrote on last edited by
            #21

            Wjousts wrote: The specifications concerning the behavor of postfix and prefix increment aren't relavent. WHAT?! :confused: Then why have a language specification at all? They detail the inner workings of the instruction set and execution order. According to the C/C++ language specifications, the value should be 6. Stop applying C/C++ specifications to C#. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

            W 1 Reply Last reply
            0
            • D Dave Kreskowiak

              Wjousts wrote: The specifications concerning the behavor of postfix and prefix increment aren't relavent. WHAT?! :confused: Then why have a language specification at all? They detail the inner workings of the instruction set and execution order. According to the C/C++ language specifications, the value should be 6. Stop applying C/C++ specifications to C#. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

              W Offline
              W Offline
              Wjousts
              wrote on last edited by
              #22

              Dave Kreskowiak wrote: WHAT?! Then why have a language specification at all? They detail the inner workings of the instruction set and execution order. Not relevant to this problem. You are still not getting this. i++ is logically equavalent to i=i+1 correct? If i do i=i+1 I should get the same value in i as I would if I just did i++, correct? So then: int i = 5; i = i++; should give the same result as: int i = 5; i = i; i = i + 1; Correct? Therefore i should equal 6. Show me where the flaw is? Both the assignment and the increment have to happen before the code has finished executing therefore it really doesn't matter which one happens first. Compare these: int i = 5; i++; Console.Writeline(i.ToString()); int i = 5; ++i; Console.Writeline(i.ToString()); What's the output in both cases? Would you agree that the postfix or prefix notation doesn't change the output in this case?

              D 1 Reply Last reply
              0
              • W Wjousts

                Dave Kreskowiak wrote: WHAT?! Then why have a language specification at all? They detail the inner workings of the instruction set and execution order. Not relevant to this problem. You are still not getting this. i++ is logically equavalent to i=i+1 correct? If i do i=i+1 I should get the same value in i as I would if I just did i++, correct? So then: int i = 5; i = i++; should give the same result as: int i = 5; i = i; i = i + 1; Correct? Therefore i should equal 6. Show me where the flaw is? Both the assignment and the increment have to happen before the code has finished executing therefore it really doesn't matter which one happens first. Compare these: int i = 5; i++; Console.Writeline(i.ToString()); int i = 5; ++i; Console.Writeline(i.ToString()); What's the output in both cases? Would you agree that the postfix or prefix notation doesn't change the output in this case?

                D Offline
                D Offline
                Dave Kreskowiak
                wrote on last edited by
                #23

                Wjousts wrote: i++ is logically equavalent to i=i+1 correct? No, it's not! i++; is equivilent to i=i+1. Your flaw is not understand the execution order of the operators and assignments you're using. This works like you want it to:

                int i = 5;
                i++;
                Console.WriteLine(i.ToString());

                You're not understanding the procedures, order, and times in which each operation takes place. It's already been explained to you in the C# Language Specifications. Wjousts wrote: Would you agree that the postfix or prefix notation doesn't change the output in this case? It's not the operators that are changing the output. It's, again, the execution order and times of the operators in question. What do you think the output of these are?:

                int i = 5;
                Console.WriteLine((i++).ToString());
                 
                int i = 5;
                Console.WriteLine((++i).ToString());

                RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                W 1 Reply Last reply
                0
                • D Dave Kreskowiak

                  Wjousts wrote: i++ is logically equavalent to i=i+1 correct? No, it's not! i++; is equivilent to i=i+1. Your flaw is not understand the execution order of the operators and assignments you're using. This works like you want it to:

                  int i = 5;
                  i++;
                  Console.WriteLine(i.ToString());

                  You're not understanding the procedures, order, and times in which each operation takes place. It's already been explained to you in the C# Language Specifications. Wjousts wrote: Would you agree that the postfix or prefix notation doesn't change the output in this case? It's not the operators that are changing the output. It's, again, the execution order and times of the operators in question. What do you think the output of these are?:

                  int i = 5;
                  Console.WriteLine((i++).ToString());
                   
                  int i = 5;
                  Console.WriteLine((++i).ToString());

                  RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                  W Offline
                  W Offline
                  Wjousts
                  wrote on last edited by
                  #24

                  Dave Kreskowiak wrote: Wjousts wrote: i++ is logically equavalent to i=i+1 correct? No, it's not! i++; is equivilent to i=i+1. So no, you agree??? You're still missing the point. First, this wasn't my question. i = i++ is redudant and a silly thing to try and do in the first place! The point is that in that statement that the original poster posted the incremement part, the i++ is NEVER EXECUTED. Where in the C# specification does it say that the compiler will randomly ignore increment statements whenever it feel like it? Please so me the exact section that says that. It's not an issue of execution order because ALL THE STATEMENTS ARE SUPPOSED TO BE EXECUTED!

                  D 1 Reply Last reply
                  0
                  • W Wjousts

                    Dave Kreskowiak wrote: Wjousts wrote: i++ is logically equavalent to i=i+1 correct? No, it's not! i++; is equivilent to i=i+1. So no, you agree??? You're still missing the point. First, this wasn't my question. i = i++ is redudant and a silly thing to try and do in the first place! The point is that in that statement that the original poster posted the incremement part, the i++ is NEVER EXECUTED. Where in the C# specification does it say that the compiler will randomly ignore increment statements whenever it feel like it? Please so me the exact section that says that. It's not an issue of execution order because ALL THE STATEMENTS ARE SUPPOSED TO BE EXECUTED!

                    D Offline
                    D Offline
                    Dave Kreskowiak
                    wrote on last edited by
                    #25

                    Wjousts wrote: No, it's not! i++; is equivilent to i=i+1. So no, you agree??? Whoops! My typeo. i++ is equivelent to i=i+1. But, that not what i=i++; is saying. Wjousts wrote: It's not an issue of execution order because ALL THE STATEMENTS ARE SUPPOSED TO BE EXECUTED! Yeah, all the statements are supposed to be executed, DUH! The problem is in which order the various PIECES of those statements are executed! Want proof of the execution order of the expression? One more time...

                    int i = 5;
                    Console.WriteLine((i++).ToString()); ' Result: 5
                     
                    int i = 5;
                    Console.WriteLine((++i).ToString()); ' Result: 6

                    I understand perfectly what the code is doing and I know exactly why it's coming up with the results it is. It's your argument that I don't get. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                    W 1 Reply Last reply
                    0
                    • D Dave Kreskowiak

                      Wjousts wrote: No, it's not! i++; is equivilent to i=i+1. So no, you agree??? Whoops! My typeo. i++ is equivelent to i=i+1. But, that not what i=i++; is saying. Wjousts wrote: It's not an issue of execution order because ALL THE STATEMENTS ARE SUPPOSED TO BE EXECUTED! Yeah, all the statements are supposed to be executed, DUH! The problem is in which order the various PIECES of those statements are executed! Want proof of the execution order of the expression? One more time...

                      int i = 5;
                      Console.WriteLine((i++).ToString()); ' Result: 5
                       
                      int i = 5;
                      Console.WriteLine((++i).ToString()); ' Result: 6

                      I understand perfectly what the code is doing and I know exactly why it's coming up with the results it is. It's your argument that I don't get. RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                      W Offline
                      W Offline
                      Wjousts
                      wrote on last edited by
                      #26

                      Dave Kreskowiak wrote: Whoops! My typeo. i++ is equivelent to i=i+1. But, that not what i=i++; is saying. Huh :confused: One more time: int i = 5; Console.WriteLine((i++).ToString()); ' Result: 5 Console.WriteLine(i).ToString(); // Result: 6 int i = 5; Console.WriteLine((++i).ToString()); ' Result: 6 Console.WriteLine(i).ToString(); // Result: 6 You need to look at the value of i AFTER both commands have been executed, that is what you are still not seeing. In fact, have you even looked at the IL generated by the original code? .locals init ([0] int32 i) IL_0000: ldc.i4.5 // load 5 onto stack as 32 bit int IL_0001: stloc.0 // assignment of i IL_0002: ldloc.0 // load local varible onto stack (5 is top of stack) IL_0003: dup // Duplicate top value on stack (stack - 5,5) IL_0004: ldc.i4.1 // Load 1 onto stack (stack - 5,5,1) IL_0005: add // Add top to values on stack - result 6 (stack - 5,6) IL_0006: stloc.0 // load 6 into i (stack - 5, i = 6) IL_0007: stloc.0 // load 5 into i (i = 5) This is the "strange" code the original poster referred to and you can see that it is indeed confused. My best intepretation of what it is trying to do is that it actually does the increment FIRST and then it does the assignment, but with the old value of i instead of the new value. That is why this is a bug. This isn't what it supposed to happen according to the language specification. Compare it to the IL from C++: .locals init ([0] int32 i) IL_0000: ldc.i4.5 IL_0001: stloc.0 // Assign i IL_0002: ldloc.0 // push i onto stack (stack 5) IL_0003: stloc.0 // pop from stack and store in i (stack empty) i = i IL_0004: ldloc.0 // push i onto stack (stack 5) IL_0005: ldc.i4.1 // push 1 onto stack (stack 5,1) IL_0006: add // add (stack 6) IL_0007: stloc.0 // pop from stack and store in i (stack empty) i++ The C# compiler should generate the basically the same IL as C++ as doesn't. -- modified at 5:21 Tuesday 27th September, 2005

                      D 1 Reply Last reply
                      0
                      • W Wjousts

                        Dave Kreskowiak wrote: Whoops! My typeo. i++ is equivelent to i=i+1. But, that not what i=i++; is saying. Huh :confused: One more time: int i = 5; Console.WriteLine((i++).ToString()); ' Result: 5 Console.WriteLine(i).ToString(); // Result: 6 int i = 5; Console.WriteLine((++i).ToString()); ' Result: 6 Console.WriteLine(i).ToString(); // Result: 6 You need to look at the value of i AFTER both commands have been executed, that is what you are still not seeing. In fact, have you even looked at the IL generated by the original code? .locals init ([0] int32 i) IL_0000: ldc.i4.5 // load 5 onto stack as 32 bit int IL_0001: stloc.0 // assignment of i IL_0002: ldloc.0 // load local varible onto stack (5 is top of stack) IL_0003: dup // Duplicate top value on stack (stack - 5,5) IL_0004: ldc.i4.1 // Load 1 onto stack (stack - 5,5,1) IL_0005: add // Add top to values on stack - result 6 (stack - 5,6) IL_0006: stloc.0 // load 6 into i (stack - 5, i = 6) IL_0007: stloc.0 // load 5 into i (i = 5) This is the "strange" code the original poster referred to and you can see that it is indeed confused. My best intepretation of what it is trying to do is that it actually does the increment FIRST and then it does the assignment, but with the old value of i instead of the new value. That is why this is a bug. This isn't what it supposed to happen according to the language specification. Compare it to the IL from C++: .locals init ([0] int32 i) IL_0000: ldc.i4.5 IL_0001: stloc.0 // Assign i IL_0002: ldloc.0 // push i onto stack (stack 5) IL_0003: stloc.0 // pop from stack and store in i (stack empty) i = i IL_0004: ldloc.0 // push i onto stack (stack 5) IL_0005: ldc.i4.1 // push 1 onto stack (stack 5,1) IL_0006: add // add (stack 6) IL_0007: stloc.0 // pop from stack and store in i (stack empty) i++ The C# compiler should generate the basically the same IL as C++ as doesn't. -- modified at 5:21 Tuesday 27th September, 2005

                        D Offline
                        D Offline
                        Dave Kreskowiak
                        wrote on last edited by
                        #27

                        Wjousts wrote: You need to look at the value of i AFTER both commands have been executed, that is what you are still not seeing. I'm looking at the value of i before the expression is evaluated, DURING THE EXPRESSION EVALUATION, AND after! And, I',m paying attention to the language specification that describes how each language evaluates and executes it's statements and expressions. You're not. You just see the exact same syntax in two different languages and assume that they MUST work exactly the same and generate the exact same code and results. NOTHING could be further from the truth! Stop equating C# to C++! They are NOT the same! Wjousts wrote: In fact, have you even looked at the IL generated by the original code? Yes, I have. And the code generated follow the C# language specification exactly. No surprise here. It does NOT, on the other hand, match the C++ language specification. No surprise here either... RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                        W 1 Reply Last reply
                        0
                        • D Dave Kreskowiak

                          Wjousts wrote: You need to look at the value of i AFTER both commands have been executed, that is what you are still not seeing. I'm looking at the value of i before the expression is evaluated, DURING THE EXPRESSION EVALUATION, AND after! And, I',m paying attention to the language specification that describes how each language evaluates and executes it's statements and expressions. You're not. You just see the exact same syntax in two different languages and assume that they MUST work exactly the same and generate the exact same code and results. NOTHING could be further from the truth! Stop equating C# to C++! They are NOT the same! Wjousts wrote: In fact, have you even looked at the IL generated by the original code? Yes, I have. And the code generated follow the C# language specification exactly. No surprise here. It does NOT, on the other hand, match the C++ language specification. No surprise here either... RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                          W Offline
                          W Offline
                          Wjousts
                          wrote on last edited by
                          #28

                          Dave Kreskowiak wrote: I'm looking at the value of i before the expression is evaluated, DURING THE EXPRESSION EVALUATION, AND after! No your not. Look at the original question. The question asked what is the value of i AFTER the code (all of it) has been executed. Dave Kreskowiak wrote: I',m paying attention to the language specification Where in the specification does it say that i++ does nothing?

                          D 1 Reply Last reply
                          0
                          • W Wjousts

                            Dave Kreskowiak wrote: I'm looking at the value of i before the expression is evaluated, DURING THE EXPRESSION EVALUATION, AND after! No your not. Look at the original question. The question asked what is the value of i AFTER the code (all of it) has been executed. Dave Kreskowiak wrote: I',m paying attention to the language specification Where in the specification does it say that i++ does nothing?

                            D Offline
                            D Offline
                            Dave Kreskowiak
                            wrote on last edited by
                            #29

                            Wjousts wrote: No your not. Look at the original question. The question asked what is the value of i AFTER the code (all of it) has been executed. In order to explain WHY the result of the expression is what it is, you have to look at how the expression is evaluated. This is covered in the language specs and by looking at the IL. Wjousts wrote: Where in the specification does it say that i++ does nothing? I never said it "did nothing". Where on earth did you get this? RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups