Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Exception "Skips" Try-Catch Clause in MSVC x64

I'm writing a program in C++. The program has been working fine for Win32 (x86), and recently I've tried compiling it natively for x64. Of course, stuff didn't work right away.

After debugging the problem, I've managed to reproduce it with this simple code snippet:

class MyException { };

int main()
{
    try {
        for (;;) {
            try {
                std::cout << "Throwing" << std::endl;

                throw MyException();

                if (1 == 0) {
                    continue;
                }
            } catch (const MyException&) {
                std::cout << "Catch 1" << std::endl;
            }
        }
    } catch (const MyException&) {
        std::cout << "Catch 2" << std::endl;
    }

    std::cout << "Done" << std::endl;

    return 0;
}

(I'll explain the if (1==0) clause soon)

When compiling this code using MSVC for x86 (I've used 2010), the result is as expected:

Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
...

And so on, in an infinite loop.

However, compiling this code for x64 results in:

Throwing
Catch 2
Done

The exception completely skips the inner catch clause!

This only happens when the if (1 ==0) clause exists in my code. When I remove it, the exception is caught in "Catch 1" as expected.

I've tried using other compilers:

  • This bug also happens in VS 2012.
  • MinGW and MinGW-w64 work as expected.

My question: is this an MSVC bug, or is this some undefined behavior in C++ I'm missing? If this indeed is an MSVC bug, I'd love to hear some insight on the cause.

Thanks.

like image 415
Adar Arnon Avatar asked Oct 24 '13 19:10

Adar Arnon


1 Answers

This bug may have something to do with compiler optimization -- it's interesting that the linker crashes in your release build (when full optimization would theoretically be turned on).

Does your debug build have optimization completely disabled (/Od)?

Visual Studio Help also contains a statement (under "Optimization Best Practices") discouraging try/catch blocks in 64-bit code.

If you turn off optimization in the release build, the linker doesn't crash. It also won't crash (but will reproduce the bad behavior) if you remove just the "continue" statement.

if (1==0) {
//continue;
}
like image 177
Spencer Avatar answered Sep 23 '22 02:09

Spencer