use*_*329 3 c c++ gcc exception
好的,所以我需要-fexceptions允许C++异常通过C代码传播.我试图比较C++和C的结果,从我所知道的,编译的例程在程序集中是相同的,即使没有那个选项[1].这是测试:
#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);
}
Run Code Online (Sandbox Code Playgroud)
在这里,由调用者来释放资源,所以即使回调函数抛出异常也不应该泄漏.
即使这个例子似乎工作(使用简单的C++驱动程序测试)
#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;
}
Run Code Online (Sandbox Code Playgroud)
,我从GTK回调中得到了未捕获的异常错误.我的想法:
这个问题的问题是,它询问未定义结果的定义行为是什么.
C标准没有描述通过C函数抛出异常时的行为,因为它不应该发生.
C++标准没有解释通过C函数丢弃未捕获异常的机制,因为它不应该发生.
Windows Visual C++使用fs:segment寄存器进行线程本地存储,并使用线程局部数据段中的特定插槽来创建catch帧的链接列表.
抛出C++异常时,将检查链表以查找堆栈对象的析构函数和合适的catch框架.
C编译器可能不知道这些资源的C++使用,并且能够为不同目的重新使用这些插槽.如果插槽用于不兼容的功能,则会发生崩溃.
一个特定的平台和编译器可能会支持这一点,但你可以随心所欲地使用它.
gcc是一个C编译器,因此不会抛出异常.它可以创建支持异常的代码-fexception.
gnu编译器:使用异常建议用-fexceptions编译C代码并说
特别是,展开到没有异常处理数据的帧将导致运行时中止.
虽然该语句的上下文没有描述是由于被调试子句,还是由于异常机制识别非法状态并导致中止.
实际的实现将是硬件和操作系统特定的,这在问题中没有指定,对于特定的答案,应该指定这些.
extern "C"包装器,确保它是完全C++编译单元).