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. When the finally code is executed?

When the finally code is executed?

Scheduled Pinned Locked Moved C#
question
24 Posts 7 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.
  • F Offline
    F Offline
    Fired Fish Gmail
    wrote on last edited by
    #1

    try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

    N C M D F 5 Replies Last reply
    0
    • F Fired Fish Gmail

      try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

      N Offline
      N Offline
      N a v a n e e t h
      wrote on last edited by
      #2

      What happened when you tried?

      Navaneeth How to use google | Ask smart questions

      1 Reply Last reply
      0
      • F Fired Fish Gmail

        try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

        C Offline
        C Offline
        Christian Graus
        wrote on last edited by
        #3

        Well, that's a dumb question. If there's no other code, then before or after the return are basically the same thing, excepting that when the code returns, i will no longer exist. In fact, I don't think this will compile, because the scope of i is the try block, I think you need to define it outside the try for the catch to see it.

        Christian Graus Driven to the arms of OSX by Vista. "! i don't exactly like or do programming and it only gives me a headache." - spotted in VB forums. I can do things with my brain that I can't even google. I can flex the front part of my brain instantly anytime I want. It can be exhausting and it even causes me vision problems for some reason. - CaptainSeeSharp

        D 1 Reply Last reply
        0
        • F Fired Fish Gmail

          try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

          M Offline
          M Offline
          musefan
          wrote on last edited by
          #4

          I think it was an interesting question... thou I don't see why you need to ask when you can just try yourself. Thou as Christian said, you variable in the finally block is not in scope. The answer would appear that the finally code is executed after the return thou I would say that the function is not complete until after the finally block. That means whenever return is called then that is the value that will be return regardless of what is done in the finally block. I wonder what would happen if you put a return in the finally block too.... ...oh, you cant return from a finally block.

          Life goes very fast. Tomorrow, today is already yesterday.

          D 1 Reply Last reply
          0
          • F Fired Fish Gmail

            try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

            D Offline
            D Offline
            dojohansen
            wrote on last edited by
            #5

            Hi, Your code wouldn't actually compile because you've scoped i to the try block but use it also in the finally block. That said, any code of a method that executes at all *necessarily* does so *before* the method returns. BUT... your method, if you move the int i = 1; line before the try-block (so it can compile), will nonetheless return 1. Logically you can think of it as transforming the code into something like this:

            int i = 1;
            try
            {
            int returnValue = i;
            i += 3;
            return returnValue;
            }
            catch
            {
            i += 3;
            throw;
            }

            In other words, the finally code executes prior to returning, but everything else, including evaluating the return value, happens before. You can see this by taking your try-finally code, set a breakpoint at entry, and step through it using "step into" (F11 in the English Visual Studio). However, while it is *possible* to write code that is a bit confusing using try-finally or try-catch-finally, in practice there is no real problem. Catch blocks are for error handling and finally blocks are for freeing up resources. The classic example is databases and transactions: Let's say your method needs to open a connection and start a transaction to insert a record into two tables. If either insert fails you want both to fail, ensuring the consistency of your database, and regardless of how the inserts go you must always close the connection before returning from the method. In other words, error handling consists of rolling back a failed transaction, and resource cleanup consists of closing (and thus freeing up) the connection. The code thus would be something like this:

            SqlConnection cnx = new SqlConnection("Data Source=.; Initial Catalog=Northwind; Integrated Security=true");
            cnx.Open();
            SqlTransaction tx = null;
            try
            {
            tx = cnx.BeginTransaction();
            insertFirst();
            insertSecond();
            tx.Commit();
            }
            catch
            {
            if (tx != null) tx.Rollback();
            throw;
            }
            finally
            {
            cnx.Close();
            }

            If any statement in the try-block fails, control passes to the catch block. If BeginTransaction() failed tx is null and no rollback is attempted; if anything else fails we have a transaction and it is rolled back. Whether or not the operation fails, the connection is closed before the method either returns normally or re-throws the exception that occured during the try-block. Hope this helps!

            1 Reply Last reply
            0
            • C Christian Graus

              Well, that's a dumb question. If there's no other code, then before or after the return are basically the same thing, excepting that when the code returns, i will no longer exist. In fact, I don't think this will compile, because the scope of i is the try block, I think you need to define it outside the try for the catch to see it.

              Christian Graus Driven to the arms of OSX by Vista. "! i don't exactly like or do programming and it only gives me a headache." - spotted in VB forums. I can do things with my brain that I can't even google. I can flex the front part of my brain instantly anytime I want. It can be exhausting and it even causes me vision problems for some reason. - CaptainSeeSharp

              D Offline
              D Offline
              dojohansen
              wrote on last edited by
              #6

              Well that is a dumb answer because it's totally unhelpful! You're right that it won't compile, but surely you can see that the question works by simply declaring i at the method level instead. And there is in fact a subtle effect of the try-finally.

              int foo()
              {
              int i = 1;
              try { return i; }
              finally { i = 5; }
              }

              This code compiles, but what does foo() return? I think quite a lot of people would expect it to return 5, since the finally block is executed before the method returns. But the return value is *evaluated* before the finally block runs and the method returns 1. Now what would happen if we boxed the int in a class of our own?

              class BoxedInt { public int Value; }

              BoxedInt bar()
              {
              BoxedInt i = new BoxedInt() { Value = 1 };
              try { return i; }
              finally { i.Value = 5; }
              }

              While foo() returns 1, bar() returns a BoxedInt whose Value is 5. That's because BoxedInt is a class and thus a reference type, so it does not matter if the return value is evaluated before or after the finally block executes. Change BoxedInt to a struct, and bar will return a BoxedInt with Value equal to 1 as well. I'd say there's some subtlety here, so calling that a stupid question seems to me rather a stretch.

              P 1 Reply Last reply
              0
              • M musefan

                I think it was an interesting question... thou I don't see why you need to ask when you can just try yourself. Thou as Christian said, you variable in the finally block is not in scope. The answer would appear that the finally code is executed after the return thou I would say that the function is not complete until after the finally block. That means whenever return is called then that is the value that will be return regardless of what is done in the finally block. I wonder what would happen if you put a return in the finally block too.... ...oh, you cant return from a finally block.

                Life goes very fast. Tomorrow, today is already yesterday.

                D Offline
                D Offline
                dojohansen
                wrote on last edited by
                #7

                The answer is in fact more subtle: The finally block executes before the method returns, but the return value is *evaluated* before the finally block runs. Because his code works with a value type (int) the increment he did in the finally is not reflected in the return value of the method - it's as if the compiler transformed return i; to int ret = i; i += 3; return ret;, executing the finally block after evaluating the return expression, but before returning. If it had been an object (reference type) and the finally modified the state of that object, the caller would "see" the changes made by the finally block. See my replies above if you want more details.

                M 1 Reply Last reply
                0
                • D dojohansen

                  The answer is in fact more subtle: The finally block executes before the method returns, but the return value is *evaluated* before the finally block runs. Because his code works with a value type (int) the increment he did in the finally is not reflected in the return value of the method - it's as if the compiler transformed return i; to int ret = i; i += 3; return ret;, executing the finally block after evaluating the return expression, but before returning. If it had been an object (reference type) and the finally modified the state of that object, the caller would "see" the changes made by the finally block. See my replies above if you want more details.

                  M Offline
                  M Offline
                  musefan
                  wrote on last edited by
                  #8

                  That's the same thing I said just using different words, so maybe before correcting me you should have spent time understanding what I said and not just repeating me and thinking that you have given a different answer.

                  Life goes very fast. Tomorrow, today is already yesterday.

                  D 1 Reply Last reply
                  0
                  • M musefan

                    That's the same thing I said just using different words, so maybe before correcting me you should have spent time understanding what I said and not just repeating me and thinking that you have given a different answer.

                    Life goes very fast. Tomorrow, today is already yesterday.

                    D Offline
                    D Offline
                    dojohansen
                    wrote on last edited by
                    #9

                    I'll try to remember you're an ungrateful little brat. Actually you didn't say half of what I did, although you did say something vaguely similar. (Don't reply just to repeat a claim - readers can just look at the thread and decide for themselves.)

                    J M 2 Replies Last reply
                    0
                    • D dojohansen

                      I'll try to remember you're an ungrateful little brat. Actually you didn't say half of what I did, although you did say something vaguely similar. (Don't reply just to repeat a claim - readers can just look at the thread and decide for themselves.)

                      J Offline
                      J Offline
                      J4amieC
                      wrote on last edited by
                      #10

                      You know, going round insulting the regulars isn't a good way to endear yourself to a community.

                      D 1 Reply Last reply
                      0
                      • F Fired Fish Gmail

                        try { int i = 1; int j = 2; return i; } finally { i += 3; } The code in the finally statement will be executed ? when? before return or after return ?

                        F Offline
                        F Offline
                        Fired Fish Gmail
                        wrote on last edited by
                        #11

                        Thank you for everyone's replies. I saw one question that if there is the return statement in the try block, and when the finally is to be executed. I thought that when return, the finally statement will not be executed. otherwise ,if input one return statement in the finally or change the variable value in the finally block, the result will be changed. The code in the subject can not be compiled, because I define the variable i and j of the int type in the try block. Now I modify them. Following is the new code: using System; using System.Collections.Generic; using System.Text; namespace Finally { class Program { static void Main(string[] args) { int z = func1(); } static public int func1() { int i = 1; int j = 2; try { i = 110; j = 119; return i; } finally { i += 3; } } } } I find that the return statement can not be typed in the finally block. From the asm code, we can find that the function save the return value and then jump to the finally block to execute. so the result will not be influenced. Following is the asm code. using System; using System.Collections.Generic; using System.Text; namespace Finally { class Program { static void Main(string[] args) { int z = func1(); } static public int func1() { 00000000 push ebp 00000001 mov ebp,esp 00000003 push edi 00000004 push esi 00000005 push ebx 00000006 sub esp,38h 00000009 xor eax,eax 0000000b mov dword ptr [ebp-10h],eax 0000000e xor eax,eax 00000010 mov dword ptr [ebp-1Ch],eax 00000013 cmp dword ptr ds:[00AE8364h],0 0000001a je 00000021 0000001c call 792611C6 00000021 xor edx,edx 00000023 mov dword ptr [ebp-3Ch],edx 00000026 xor edx,edx 00000028 mov dword ptr [ebp-40h],edx 0000002b xor edx,edx 0000002d mov dword ptr [ebp-44h],edx 00000030 nop int i = 1; 00000031 mov dword ptr [ebp-3Ch],1 int j = 2; 00000038 mov dword ptr [ebp-40h],2 try { 0000003f nop i = 110; 00000040 mov

                        D 1 Reply Last reply
                        0
                        • J J4amieC

                          You know, going round insulting the regulars isn't a good way to endear yourself to a community.

                          D Offline
                          D Offline
                          dojohansen
                          wrote on last edited by
                          #12

                          And you think I deserved the snotty reply he gave me? I think I contributed a very clear explanation of what exactly happens and provided more information than he had done (his explanation was onto something, but didn't point out how reference versus value types would affect the outcome - so I had something to add). It's up to you whether you rate contributions according to how regularly the author posts messages. I'd rather rate them for quality and value. And I reserve the right to return rudeness to anyone, regular or not.

                          1 Reply Last reply
                          0
                          • F Fired Fish Gmail

                            Thank you for everyone's replies. I saw one question that if there is the return statement in the try block, and when the finally is to be executed. I thought that when return, the finally statement will not be executed. otherwise ,if input one return statement in the finally or change the variable value in the finally block, the result will be changed. The code in the subject can not be compiled, because I define the variable i and j of the int type in the try block. Now I modify them. Following is the new code: using System; using System.Collections.Generic; using System.Text; namespace Finally { class Program { static void Main(string[] args) { int z = func1(); } static public int func1() { int i = 1; int j = 2; try { i = 110; j = 119; return i; } finally { i += 3; } } } } I find that the return statement can not be typed in the finally block. From the asm code, we can find that the function save the return value and then jump to the finally block to execute. so the result will not be influenced. Following is the asm code. using System; using System.Collections.Generic; using System.Text; namespace Finally { class Program { static void Main(string[] args) { int z = func1(); } static public int func1() { 00000000 push ebp 00000001 mov ebp,esp 00000003 push edi 00000004 push esi 00000005 push ebx 00000006 sub esp,38h 00000009 xor eax,eax 0000000b mov dword ptr [ebp-10h],eax 0000000e xor eax,eax 00000010 mov dword ptr [ebp-1Ch],eax 00000013 cmp dword ptr ds:[00AE8364h],0 0000001a je 00000021 0000001c call 792611C6 00000021 xor edx,edx 00000023 mov dword ptr [ebp-3Ch],edx 00000026 xor edx,edx 00000028 mov dword ptr [ebp-40h],edx 0000002b xor edx,edx 0000002d mov dword ptr [ebp-44h],edx 00000030 nop int i = 1; 00000031 mov dword ptr [ebp-3Ch],1 int j = 2; 00000038 mov dword ptr [ebp-40h],2 try { 0000003f nop i = 110; 00000040 mov

                            D Offline
                            D Offline
                            dojohansen
                            wrote on last edited by
                            #13

                            Indeed; this is what I explained, but thanks for the disassembly to prove it. Just one tip: Wrap your code in <pre></pre> tags and it will make a world of difference for readability!

                            F 1 Reply Last reply
                            0
                            • D dojohansen

                              Indeed; this is what I explained, but thanks for the disassembly to prove it. Just one tip: Wrap your code in <pre></pre> tags and it will make a world of difference for readability!

                              F Offline
                              F Offline
                              Fired Fish Gmail
                              wrote on last edited by
                              #14

                              I know that, thks.

                              1 Reply Last reply
                              0
                              • D dojohansen

                                I'll try to remember you're an ungrateful little brat. Actually you didn't say half of what I did, although you did say something vaguely similar. (Don't reply just to repeat a claim - readers can just look at the thread and decide for themselves.)

                                M Offline
                                M Offline
                                musefan
                                wrote on last edited by
                                #15

                                Ungrateful for what? you didn't post anything that was designed to help me. I said that the return is executed before the 'finally code' but the function is not complete (returned) until the finally code is processed.

                                dojohansen wrote:

                                Actually you didn't say half of what I did

                                I was not trying to claim to have said what you did - I said you said what I said. Anyway, my point is I don't appreciate something thinking there correcting me by basically saying the same thing. If I said: "1 + 1 = 2" and then someone said: "No, Actually, one add one equals 2" then that person would be considered some sort of idiot, don't you think?

                                Life goes very fast. Tomorrow, today is already yesterday.

                                M 1 Reply Last reply
                                0
                                • M musefan

                                  Ungrateful for what? you didn't post anything that was designed to help me. I said that the return is executed before the 'finally code' but the function is not complete (returned) until the finally code is processed.

                                  dojohansen wrote:

                                  Actually you didn't say half of what I did

                                  I was not trying to claim to have said what you did - I said you said what I said. Anyway, my point is I don't appreciate something thinking there correcting me by basically saying the same thing. If I said: "1 + 1 = 2" and then someone said: "No, Actually, one add one equals 2" then that person would be considered some sort of idiot, don't you think?

                                  Life goes very fast. Tomorrow, today is already yesterday.

                                  M Offline
                                  M Offline
                                  musefan
                                  wrote on last edited by
                                  #16

                                  Just for any who are interested then dojohansen sent me an email with the following content... Hi, I don't want the thread to degenerate into a petty fight between you and me about whether or not we contributed something. But I do want to replay to *you* - hence this private message. musefan wrote:Ungrateful for what? you didn't post anything that was designed to help me. I said that the return is executed before the 'finally code' but the function is not complete (returned) until the finally code is processed. I definitely said something that was meant to help, although it was not meant for you specifically. A reply in a forum is a reply to a message, not to the author of the message - if I wanted to address you I'd send a private message like this one. What you said (as you accurately repeat in the above quote) is not wrong, but nor is it very precise. There's no mention of the crucial fact that the return value is evaluated before the finally executes**[I said that the 'finally block' executes after the return - which to me is the same as saying "the return value is evaluated before the finally executes"]. There is also nothing that can help your reader understand that it would make a difference if the method worked with a reference type rather than a value type[personally I see the OP as simply asking if finally code is executed before or after the return statement. Not "how do I add to a variable before returning the value?"]. So although I feel people ought to be very happy to be corrected, and I try to be so myself when I am, this message was not even an attempt to correct you. I merely tried to clarify further and add some information regarding the subtleties that arise from the fact that the return value is evaluated before the finally block runs and returned afterwards. To this, you gave a reply that was less than useless. Having first misinterpreted my message as a correction you decided to give me a snotty reply accusing me of trying to score brownie points by repeating you[I did not accuse you of 'stealing' my answer]**. Frankly I feel that if you thought that was what I was doing you should be kind enough to the rest of the community to either just forget about it, or alternatively bring it up in a private message. [the impression I got (intended or not) was that you were correcting me and then saying it was the same answer - to me that warrants a telling off] musefan wrote:Anyway, my point is I don't appreciate something thinking there corre

                                  J D 3 Replies Last reply
                                  0
                                  • M musefan

                                    Just for any who are interested then dojohansen sent me an email with the following content... Hi, I don't want the thread to degenerate into a petty fight between you and me about whether or not we contributed something. But I do want to replay to *you* - hence this private message. musefan wrote:Ungrateful for what? you didn't post anything that was designed to help me. I said that the return is executed before the 'finally code' but the function is not complete (returned) until the finally code is processed. I definitely said something that was meant to help, although it was not meant for you specifically. A reply in a forum is a reply to a message, not to the author of the message - if I wanted to address you I'd send a private message like this one. What you said (as you accurately repeat in the above quote) is not wrong, but nor is it very precise. There's no mention of the crucial fact that the return value is evaluated before the finally executes**[I said that the 'finally block' executes after the return - which to me is the same as saying "the return value is evaluated before the finally executes"]. There is also nothing that can help your reader understand that it would make a difference if the method worked with a reference type rather than a value type[personally I see the OP as simply asking if finally code is executed before or after the return statement. Not "how do I add to a variable before returning the value?"]. So although I feel people ought to be very happy to be corrected, and I try to be so myself when I am, this message was not even an attempt to correct you. I merely tried to clarify further and add some information regarding the subtleties that arise from the fact that the return value is evaluated before the finally block runs and returned afterwards. To this, you gave a reply that was less than useless. Having first misinterpreted my message as a correction you decided to give me a snotty reply accusing me of trying to score brownie points by repeating you[I did not accuse you of 'stealing' my answer]**. Frankly I feel that if you thought that was what I was doing you should be kind enough to the rest of the community to either just forget about it, or alternatively bring it up in a private message. [the impression I got (intended or not) was that you were correcting me and then saying it was the same answer - to me that warrants a telling off] musefan wrote:Anyway, my point is I don't appreciate something thinking there corre

                                    J Offline
                                    J Offline
                                    J4amieC
                                    wrote on last edited by
                                    #17

                                    He's obviously a self riteous idiot who likes the sound of his own voice (or rather the look of his own typing). Ive not even seen the name here before today, but in the last few hours he's answering question after question in the most verbose way possible.. often replying to other satisfactory answers (like yours above) just to add his 2pence worth. Ignore him. You do a great job of answering questions here.

                                    M D 2 Replies Last reply
                                    0
                                    • J J4amieC

                                      He's obviously a self riteous idiot who likes the sound of his own voice (or rather the look of his own typing). Ive not even seen the name here before today, but in the last few hours he's answering question after question in the most verbose way possible.. often replying to other satisfactory answers (like yours above) just to add his 2pence worth. Ignore him. You do a great job of answering questions here.

                                      M Offline
                                      M Offline
                                      musefan
                                      wrote on last edited by
                                      #18

                                      :) Thanks for your appreciation - I will take your advise and ignore any more responses ;)

                                      Life goes very fast. Tomorrow, today is already yesterday.

                                      1 Reply Last reply
                                      0
                                      • D dojohansen

                                        Well that is a dumb answer because it's totally unhelpful! You're right that it won't compile, but surely you can see that the question works by simply declaring i at the method level instead. And there is in fact a subtle effect of the try-finally.

                                        int foo()
                                        {
                                        int i = 1;
                                        try { return i; }
                                        finally { i = 5; }
                                        }

                                        This code compiles, but what does foo() return? I think quite a lot of people would expect it to return 5, since the finally block is executed before the method returns. But the return value is *evaluated* before the finally block runs and the method returns 1. Now what would happen if we boxed the int in a class of our own?

                                        class BoxedInt { public int Value; }

                                        BoxedInt bar()
                                        {
                                        BoxedInt i = new BoxedInt() { Value = 1 };
                                        try { return i; }
                                        finally { i.Value = 5; }
                                        }

                                        While foo() returns 1, bar() returns a BoxedInt whose Value is 5. That's because BoxedInt is a class and thus a reference type, so it does not matter if the return value is evaluated before or after the finally block executes. Change BoxedInt to a struct, and bar will return a BoxedInt with Value equal to 1 as well. I'd say there's some subtlety here, so calling that a stupid question seems to me rather a stretch.

                                        P Offline
                                        P Offline
                                        PIEBALDconsult
                                        wrote on last edited by
                                        #19

                                        So... you did try it, but asked the question anyway? :confused:

                                        D 1 Reply Last reply
                                        0
                                        • P PIEBALDconsult

                                          So... you did try it, but asked the question anyway? :confused:

                                          D Offline
                                          D Offline
                                          dojohansen
                                          wrote on last edited by
                                          #20

                                          Now that got me nicely confused. You replied to my message so presumably "you" means me. But what "it" and "the question" refers to is less clear. I tried many things including compiling and running the various code snippets I've put up on this thread. I may have asked questions too, but I am not the OP so if you were referring to the original message that might explain the confusion. If you did mean I tried something (and consequently found out what it does) and still asked what it does, let me know what it was and I will attempt to communicate whatever it was I was wondering about more clearly. :)

                                          P 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