Exception 可移植地处理C+中的异常错误+; 我正在研究将一个Visual C++应用移植到GCC(应该在明文和Linux上构建)。

Exception 可移植地处理C+中的异常错误+; 我正在研究将一个Visual C++应用移植到GCC(应该在明文和Linux上构建)。,exception,visual-c++,gcc,cross-platform,portability,Exception,Visual C++,Gcc,Cross Platform,Portability,现有代码使用\uuuuu try{…}\uuu,除了(1){…}块之外的一些地方,因此几乎没有任何东西(可能是内存不足类型错误?)会使程序在不进行一些最小日志记录的情况下退出 使用GCC进行类似操作的选项有哪些 编辑:感谢VisualStudio中指向/EH选项的指针,我现在需要的是一些关于如何在Linux上处理信号的示例。我从2002年就发现了 除了SIGFPE和SIGSEVG之外,我还应该注意哪些信号?(最关心的是那些可能从我做错的事情中长大的人) 赏金信息: 我希望我的应用程序能够在退出之

现有代码使用
\uuuuu try{…}\uuu,除了(1){…}
块之外的一些地方,因此几乎没有任何东西(可能是内存不足类型错误?)会使程序在不进行一些最小日志记录的情况下退出

使用GCC进行类似操作的选项有哪些

编辑:感谢VisualStudio中指向/EH选项的指针,我现在需要的是一些关于如何在Linux上处理信号的示例。我从2002年就发现了

除了
SIGFPE
SIGSEVG
之外,我还应该注意哪些信号?(最关心的是那些可能从我做错的事情中长大的人)

赏金信息: 我希望我的应用程序能够在退出之前自行记录尽可能多的错误情况

我可能会收到哪些信号,哪些信号通常不可能在之后记录错误消息?(内存不足,还有什么?)

如何以可移植的方式处理异常和(最重要的)信号,使代码至少在Linux和MingW上工作相同#ifdef还可以


<> P>我之所以不使用一个记录失败的包装过程是因为性能原因,我把一些数据写入磁盘直到最后一分钟,所以如果有什么问题,我想在退出之前尝试所有的数据写入。< /P> < P>为什么不使用C++标准的异常而不是MSFT的专有扩展?C++有一个异常处理概念。
struct my_exception_type : public logic_error {
    my_exception_type(char const* msg) : logic_error(msg) { }
};

try {
    throw my_exception_type("An error occurred");
} catch (my_exception_type& ex) {
    cerr << ex.what << endl;
}
<>但是,在C++中,这不是很有效,因为创建这样的通用包装器意味着编译器必须在每个后续堆栈帧中插入代码(不像在.NET中这样的托管系统中,异常处理不需要额外的成本,只要没有抛出异常)。会更便于携带,但可能不会捕获那么多。它取决于编译器设置和环境

使用默认VC++设置,异步(SEH)错误不传递到C++ EH基础设施;要捕获它们,您需要使用SEH处理程序(\uuuuu try/\uuuu except)。VC++允许您通过C++错误处理来路由SEH错误,这允许捕获(…)捕获SEH错误;这包括内存错误,例如空指针取消引用


然而,在Linux上,Windows使用SEH处理的许多错误都是通过信号指示的。这些永远不会被try/catch捕获;要处理这些异常,您需要一个信号处理程序。

为了可移植性,需要尝试的一件事是对大多数普通异常使用try-catch块,然后设置一个终止处理程序(set_-terminate_-handler),使其在灾难性退出条件下具有最小的可用钩子。您还可以尝试添加类似atexit或on_退出处理程序的内容。当然,当您输入这些函数时,您的执行环境可能会异常或损坏,因此请注意您假定的环境是否正常

最后,当使用常规的尝试catch对时,可以考虑使用函数尝试块,而不是在函数的正文中打开一个尝试块:

int foo(int x) try {
  // body of foo
} catch (...) {
   // be careful what's done here!
}

它们是一个相对未知的C++块,在某些情况下,即使在部分(小规模)堆栈损坏的情况下,也可能提供恢复。

最后,是的,您可能想研究哪些信号可以自己继续处理,或者可能中止,如果您希望处理机制少,可以考虑调用新操作符的非抛出版本,并编译以在需要时不生成浮点异常。(您始终可以在FP结果上检查isnan(.)、isfinite(.),以保护自己)

在最后一点上,请注意:我注意到,在linux和windows下,浮点结果分类函数可以位于不同的头中……因此,您可能必须对这些包含进行条件化


如果你觉得有点顽皮,那就用setjmp和longjmp(这是个笑话…)来写吧。

一种易于使用、可移植且几乎不使用任何资源的方法是捕获空类。我知道这一点一开始听起来可能有些奇怪,但它可能非常有用

下面是我为另一个同样适用于您的问题的问题所做的示例:

此外,您可以有多个捕获:

try
{
   /* code that may throw exceptions */
}
catch (Error1 e1)
{
   /* code if Error1 is thrown */
}
catch (Error2 e2)
{
   /* code if Error2 is thrown */
}
catch (...)
{
   /* any exception that was not expected will be caught here */
}

< >使用C++ >异常> catch(…)>代码>已经使你处于一个暮光之境。

试图捕获未被<代码> catch(…)>代码>捕获的错误,将其直接置于未定义的行为中。没有C++代码保证工作。您的最小日志代码可能会导致导弹启动。

我的建议是,甚至不要试图捕捉(…)。只捕捉可以有意义地安全地记录并让操作系统处理其余(如果有的话)的异常


如果在根原因之上错误处理代码失败,事后调试会变得丑陋。

OP正在寻找比C++语言级异常更低级例外条件的东西。在POSIX Word中,这意味着为(大多数)安装信号处理程序。一切。在MSVC中,uuuu try/uuu catch机制可以正确处理陷阱的类似故障(包括Win32等效的SEGFAULT)。但是您可以使用标准的
try
/
catch
,将MSVC配置为捕获SEH,如DRVC所述。
try
{
   /* code that may throw exceptions */
}
catch (Error1 e1)
{
   /* code if Error1 is thrown */
}
catch (Error2 e2)
{
   /* code if Error2 is thrown */
}
catch (...)
{
   /* any exception that was not expected will be caught here */
}