R..*_*R.. 14 c c++ exception-handling stack-unwinding longjmp
是否有主要的C/C++实现,其中longjmp函数"展开",即它与自动存储对象的析构函数__attribute__((__cleanup__(...))),POSIX线程取消处理程序等交互,而不仅仅是恢复由setjmp?保存的寄存器上下文?我对使用此属性的POSIX实现的存在(或不存在)特别感兴趣,但C/C++通常也很有趣.
对于赏金,我正在寻找符合POSIX或至少类似POSIX的系统,而不是已经提到过的Windows.
小智 0
Interix (SUA) 默认情况下不调用析构函数,但在 x86 模式下,确实有一个选项。
采取这个测试程序,保存为test.cc:
#include <stdio.h>
#include <setjmp.h>
struct A {
~A() { puts("~A"); }
};
jmp_buf buf;
void f() {
A a;
longjmp(buf, 1);
}
int main() {
if (setjmp (buf))
return 0;
f();
}
Run Code Online (Sandbox Code Playgroud)
Interix 的行为方式如下。为简洁起见,我省略了所需的正确设置PATH。
$ cc -mx86 test.cc && ./a.out $ cc -mx86 -X /EHa test.cc && ./a.out cl:命令行警告 D9025:用“/EHa”覆盖“/EHs” ~A $ cc -mamd64 test.cc && ./a.out $ cc -mamd64 -X /EHa test.cc && ./a.out cl:命令行警告 D9025:用“/EHa”覆盖“/EHs” $
注释表明cc -X /EHa不符合 POSIX,例如因为/EHa会捕获信号。这并不完全正确:
$ 猫测试.cc
#include <信号.h>
int main() {
尝试 {
提高(SIGFPE);
} 抓住 (...) {
// 忽略
}
}
$ cc -mx86 -X /EHa test.cc && ./a.out
cl:命令行警告 D9025:用“/EHa”覆盖“/EHs”
浮点异常(核心转储)
如果我更改raise(SIGFPE)为除以零,我确实看到异常处理程序捕获了它,但 POSIX 和 C++ 都不需要任何特定的行为,因此这不会影响一致性。也不是所有异步信号都被捕获:对于这个程序:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigint(int signal) {
puts("sigint");
exit(0);
}
int main() {
signal(SIGINT, sigint);
try {
for (;;) ;
} catch (...) {
// ignore
}
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,在 Ctrl-C 之后打印“sigint”。我看不出有什么理由声称此实现无法满足 POSIX 要求。
| 归档时间: |
|
| 查看次数: |
2251 次 |
| 最近记录: |