Ok, so I need -fexceptions to allow a C++ exception to propagate through C code. I tried to compare the results from both C++ and C, and, from what I can tell, the compiled routines are identical at the assembly, even without that option [1]. Here is the test:
#include <unistd.h>
typedef int (*Callback)(void* param,void* buffer,int n);
void write_wrapper(int fd,const void* buffer,int n)
{
const char* temp=(const char*)buffer;
while(n!=0)
{
int k=write(fd,temp,n);
n-=k;
temp+=k;
}
}
int test(Callback cb,void* cb_param)
{
char buffer[1024];
int n=0;
do
{
n=cb(cb_param,buffer,1024);
write_wrapper(STDOUT_FILENO,buffer,n);
}
while(n!=1024);
}
int test2(Callback cb,void* cb_param)
{
char more_stack_space_please[1024]={0};
cb(cb_param,more_stack_space_please,1024);
write_wrapper(STDOUT_FILENO,more_stack_space_please,1024);
test(cb,cb_param);
}
Here, it is up to the caller to free resources, so there should be no leak even though the callback function throws an exception.
Even though this example appears to work (tested with simple C++ driver)
#include "lib.h"
#include <cstdio>
class Resource
{
public:
Resource()
{fprintf(stderr,"A Resource\n");}
~Resource()
{fprintf(stderr,"Not a Resource\n");}
};
int main()
{
try
{
Resource foo;
test([](void* cb_param,void* buffer, int n)->int
{
Resource bar;
throw "test";
},nullptr);
test2([](void* cb_param,void* buffer, int n)->int
{
throw "test2";
},nullptr);
}
catch(const char* err)
{
fprintf(stderr,"Error: %s\n",err);
return -1;
}
return 0;
}
, I have got uncaught exception errors from GTK callbacks. My thoughts:
- GTK is a shared library, so maybe it only affects the linker, and not the code generator
- GTK (and GLib) contains a lot strange hacks, that may screw things up