Sorry, I should clarify that. Destructors for stack objects in C
functions aren't called when an exception is thrown. Testcase...

C:\>(type t.cpp) && (cl /nologo /EHsc t.cpp)
struct Object
{
    static int counter;
    Object() {
        Object::counter += 1;
    }
    ~Object() {
        Object::counter -= 1;
    }
};

/* static */
int Object::counter = 0;

extern "C" {

int extern_c_function (int x, int y, int (*fun)(int, int))
{
    Object obj;

    if (fun)
        return fun (x, y);

    return 0;
}

int div_throw (int x, int y)
{
    Object obj;

    if (0 == y)
        throw y;

    return x / y;
}

}   // extern "C"


int main (int argc, char *argv[])
{
    const int x = argc < 2 ? 0 : int (*argv [1]) - '0';
    const int y = argc < 3 ? 0 : int (*argv [2]) - '0';

    try {
        extern_c_function (x, y, div_throw);
    }
    catch (int res) {
        // nothing
    }

    return Object::counter != 0;
}
t.cpp
t.cpp(32) : warning C4297: 'div_throw' : function assumed not to throw
an exception but does
        The function is extern "C" and /EHc was specified

C:\>t 1 1

C:\>if errorlevel 1 (echo failure) else (echo success!)
success!

C:\>t 1 0

C:\>if errorlevel 1 (echo failure!) else (echo success!)
failure!

>-----Original Message-----
>From: Travis Vitek [mailto:[EMAIL PROTECTED] 
>Sent: Tuesday, August 14, 2007 5:18 PM
>To: stdcxx-dev@incubator.apache.org
>Subject: RE: svn commit: r565959 - 
>/incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp
>
>
>Martin,
>
>I'm not sure if you're aware, but I don't believe that the destructors
>for stack objects inside the C functions will be called. I know that
>this is the case for MSVC7/8. This isn't an issue for your 
>testcase, but
>it may be an issue for the functions invoked by __rw_once.
>
>I think this is by design, but I found it a little weird that the ascii
>value of the first character of each parameter is passed to
>div_throw/div_nothrow. I had the urge to add modify the argument
>processing lines to something more like this so that I could pass
>arguments and get the expected results.
>
>    const int x = argc < 2 ? 0 : int (*argv [1]) - '0';
>    const int y = argc < 3 ? 0 : int (*argv [2]) - '0';
>
>Travis
>
>>

Reply via email to