Can return throw an exception?

13

While playing with C# I found that following snippet:

public int F() 
{
    try 
    {
        return 0;
    } 
    catch (Exception)
    {
        return -1;
    }
}

This generates the following asm:

Program.F()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push esi
    L0004: sub esp, 0x14
    L0007: xor eax, eax
    L0009: mov [ebp-0x18], eax
    L000c: mov [ebp-0x14], eax
    L000f: mov [ebp-0x10], eax
    L0012: mov [ebp-0xc], eax
    L0015: xor esi, esi
    L0017: jmp short L0023
    L0019: mov esi, 0xffffffff
    L001e: call 0x6fb2d4d3
    L0023: mov eax, esi
    L0025: lea esp, [ebp-4]
    L0028: pop esi
    L0029: pop ebp
    L002a: ret

And when I remove the try and catch block:

public int F() 
{
    return 0;
}

then the generated output is:

Program.F()
    L0000: xor eax, eax
    L0002: ret

Question

As you can see JIT (Release) knows that it'll not return -1 (you can not find any branches that'll jump to return -1 case), but it does generate the try block for return 0 case. The question is can the return statement throw an exception or why does JIT generate asm for it?

Note

In contrast: this is what outputs g++(O2) for C++.

int 
f(void *this_) {
    try {
        return 0;
    }
    catch(...) {
        return -1;
    }
}

asm

f(void*):
        xor     eax, eax
        ret
c#
assembly
try-catch
x86-64
asked on Stack Overflow Apr 3, 2021 by (unknown user) • edited Apr 9, 2021 by Mark Rotteveel

1 Answer

6

A return statement, in general, can cause an exception due to the general purpose nature of the expression allowed in the statement — in general, an expression can cause an exception.

Should the JIT optimize exception handling knowing that the expression 0 cannot throw?  Perhaps, in a perfect world.  Is anyone complaining about this?

answered on Stack Overflow Apr 3, 2021 by Erik Eidt

User contributions licensed under CC BY-SA 3.0