Mixing C ++ exception handling and SEH (windows)

I have a function in which I call getaddrinfo()to get sockaddr*, which is memory-oriented, allocated by the system. As many people know, you need to call freeaddrinfo()to free the memory allocated by getaddrinfo ().

Now, in my function, there are several places where I can throw an exception because some function failed. My first solution was to include freeaddrinfo()in every if-block. But it looked ugly to me, because I would have to call it anyway before returning my function, so I came up with an attempt to SEH-finally ...

But the problem I ran into is that it is not allowed to code throw expressions in __try-block

Then I read in msdn and tried to change the throw statements to a helper function called from the __try block ... and voila, the compiler no longer moaned ...

Why? And is it safe? It doesn't make sense to me: /

the code:

void function()
{
    //...
    addrinfo* pFinal;
    __try
    {
        getaddrinfo(..., &pFinal);

        //if(DoSomething1() == FAILED)
        //  throw(exception);           //error C2712: Cannot use __try in functions that require object unwinding

        //but this works
        Helper();


        //...

    }
    __finally
    {
        freeaddrinfo();
    }
}


void Helper()
{
    throw(Exception);
}

EDIT:

tried the following and it works with throwing an integer, but not when I use the class as an exception:

class X
{
public:
    X(){};
    ~X(){};
};


void Helper()
{
    throw(X());
}


void base()
{
    __try
        {
            std::cout << "entering __try\n";

            Helper();

            std::cout << "leaving __try\n";
        }
        __finally
        {
            std::cout << "in __finally\n";
        }
};


int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        base();
    }
    catch(int& X)
    {
        std::cout << "caught a X" << std::endl;
    }

    std::cin.get();
    return 0;
}

Why?:/

+5
source share
3 answers

You can wrap addrinfo in a class that calls getaddrinfoin the constructor and freeaddrinfoin your destructor.

That way, he will always be freed, whether there is an exception or not.

+3
source

. ++ SEH, SEH . ++ .

PS: - . Microsoft SEH, . , , ( , , , ).

SEH , SEH.

+9
catch(int& X)
{
    std::cout << "caught a X" << std::endl;
}

It will not catch X, he catches int&. Since there is no corresponding catch block, the exception is not displayed, the stack does not unwind, and the handlers __finallydo not start.

You can put catch (...)in your entry point to the stream (which is main()for the main stream) to make sure the stack is reset, although some exceptions are unrecoverable, which is never the case with the C ++ exception.

0
source

All Articles