try-finally statement behaviour in MSVC C++
-
wrote on 28 Jun 2018, 09:41 last edited by JonB
A quick special-interest query from me. Nothing to do with Qt, but addressed to anyone using Microsoft C++ compiler (I don't, so I can't test), just for my interest.
MSVC has a non-standard extension to C++ of (https://msdn.microsoft.com/en-us/library/9xtt5hxz.aspx):
__try { // guarded code } __finally { // termination code }
I was wondering (idly) how it would handle the following:
int func() { __try { return 1; } __finally { return 2; } }
What is the return value? Or does the compiler not allow a
return
statement inside its__finally
? -
A quick special-interest query from me. Nothing to do with Qt, but addressed to anyone using Microsoft C++ compiler (I don't, so I can't test), just for my interest.
MSVC has a non-standard extension to C++ of (https://msdn.microsoft.com/en-us/library/9xtt5hxz.aspx):
__try { // guarded code } __finally { // termination code }
I was wondering (idly) how it would handle the following:
int func() { __try { return 1; } __finally { return 2; } }
What is the return value? Or does the compiler not allow a
return
statement inside its__finally
?@JonB try yourself: https://godbolt.org/
-
@JonB try yourself: https://godbolt.org/
wrote on 28 Jun 2018, 11:11 last edited by@aha_1980
Wow, thanks! I didn't know something like that existed, and didn't expect it to offer MSVC. I thought that was commercial (we use it as a paid product in our company), but I guess there's a free one too.It certainly shows me it compiles OK. However, looking through all the disassembler
mov eax, <num>
andret 0
statements I'm unsure what it would actually return if run --- do you know? -
@aha_1980
Wow, thanks! I didn't know something like that existed, and didn't expect it to offer MSVC. I thought that was commercial (we use it as a paid product in our company), but I guess there's a free one too.It certainly shows me it compiles OK. However, looking through all the disassembler
mov eax, <num>
andret 0
statements I'm unsure what it would actually return if run --- do you know?This comes from the Java world I believe. The idea is to have a handler for the both cases - an exception has occured and it was handled in the
catch()
(optional) and for when one didn't occur. Both (actually all three) paths would pass through thefinally
block before continuing on. -
This comes from the Java world I believe. The idea is to have a handler for the both cases - an exception has occured and it was handled in the
catch()
(optional) and for when one didn't occur. Both (actually all three) paths would pass through thefinally
block before continuing on.wrote on 28 Jun 2018, 11:18 last edited by JonB@kshegunov
Yes, but the question is: I am deliberately nesting areturn
statement inside atry...finally
where thefinally
has its ownreturn
statement. In this case, which value will the function return, 1 or 2? (I imagine it's the2
in the__finally
, but I wanted to confirm, given that I cannot run this.) -
@kshegunov
Yes, but the question is: I am deliberately nesting areturn
statement inside atry...finally
where thefinally
has its ownreturn
statement. In this case, which value will the function return, 1 or 2? (I imagine it's the2
in the__finally
, but I wanted to confirm, given that I cannot run this.)1
would be my best guess, but I'm no expert. -
wrote on 28 Jun 2018, 11:20 last edited by
@kshegunov
Hmm, but2
would be my guess, and we can't both be right here (unless it's a quantum computer...)? -
@kshegunov
Hmm, but2
would be my guess, and we can't both be right here (unless it's a quantum computer...)?Glancing at the asm, courtesy of @aha_1980, I'm changing my stance to
2
. At least for MSVC 2015 x86_64. -
Glancing at the asm, courtesy of @aha_1980, I'm changing my stance to
2
. At least for MSVC 2015 x86_64.wrote on 28 Jun 2018, 11:29 last edited by@kshegunov
That sounds more reasonable :)
BTW, what are thoseret 0
statements then? Does x86/x64 only useeax
for return result, becauseret 0
looks like some kind of "return 0" to me? -
@kshegunov
That sounds more reasonable :)
BTW, what are thoseret 0
statements then? Does x86/x64 only useeax
for return result, becauseret 0
looks like some kind of "return 0" to me?@JonB said in try-finally statement behaviour in MSVC C++:
Does x86/x64 only use eax for return result
Yes.
because ret 0 looks like some kind of "return 0" to me?
Means return to the near address and pop so many bytes (i.e.
0
) from the stack. -
@JonB said in try-finally statement behaviour in MSVC C++:
Does x86/x64 only use eax for return result
Yes.
because ret 0 looks like some kind of "return 0" to me?
Means return to the near address and pop so many bytes (i.e.
0
) from the stack.wrote on 28 Jun 2018, 11:47 last edited by@kshegunov
Ohhhh, the0
is "remove bytes from stack", not "pass 0 back to the caller". I would not have guessed that!!! -
@kshegunov
Ohhhh, the0
is "remove bytes from stack", not "pass 0 back to the caller". I would not have guessed that!!!@JonB said in try-finally statement behaviour in MSVC C++:
I would not have guessed that!!!
Yep, it's rather rarely used by the compilers at least from my observations. The usual thing you'd see is just:
ret
, which is the same asret 0
.
1/12