C 11中的范围(故障)
Scope(failure) in C++11?
我写了一个非常简单的解决方案,但是有人笑了,发现了一个缺陷,如下所示http://ideone.com/icwmef
#include <iostream>
#include <ostream>
#include <functional>
#include <exception>
using namespace std;
// Wrong scope(failure)
class FailBlockT
{
typedef function<void()> T;
public:
T t;
FailBlockT(T t)
{
this->t=t;
}
~FailBlockT()
{
if (std::uncaught_exception())
{
t();
}
}
};
struct Test
{
~Test()
{
try
{
FailBlockT f([]()
{
cout << "failure" << endl;
});
// there is no any exception here, but "failure" is printed.
// See output below
}
catch(...)
{
cout << "some exception" << endl;
}
}
};
int main()
{
try
{
Test t;
throw 1;
}
catch(int){}
return 0;
}
简而言之,问题是我的代码对std::uncaught_exception()
的看法。当抛出例外并执行正常的破坏者时。如果我使用示波器故障,它将查看std::uncaught_exception()
,并认为由于例外而丢失对象范围,而只是简单地走出范围。
我想不出任何好的解决方案区分离开范围通常与在其中抛出的例外。是的,我知道投掷是一个坏主意,但这就是为什么我没有注意到这个问题,因为我从未抛出过例外。
如何区分/解决此问题?
没有例外,但认为它有。
一个例外被扔了,只是不是从那里。
C 11中没有任何机制问:"是从我下方的代码中抛出的例外,但是不是从呼叫堆中的其他地方的代码?"std::uncaught_exception
正在做应该做的事情:说出当前在调用函数时解决的过程中是否有例外。而且有,所以它返回true
。
C 17添加了std::uncaught_exceptions
(请注意复数),可用于检测差异。使用这样的工具,您可以使FailBlock
对象起作用:
template<typename Func>
class FailBlockT
{
private:
int e_count_;
T t_;
public:
FailBlockT(T t) : e_count_(std::uncaught_exceptions()), t_(t) {}
FailBlock(const FailBlock &) = delete; //The type should not be mobile.
~FailBlockT()
{
if (std::uncaught_exceptions() != e_count_)
{
t_();
}
}
};
std::uncaught_exceptions()
返回呼叫时引发堆栈的异常数量。如果该对象的构造函数和击曲线期间的数字是相同的(假设它是堆栈对象),则由于使用这种类型的地方的例外,因此未调用驱动器。
但是,如果没有这个工具,就没有什么可以区分异常的示例,而当异常碰巧恰好正在发生时,而不是退出范围。因此,您必须像其他所有人一样咬住子弹和 catch 。
或只是不要将此FailBlock
的东西放在击层中。在我看来,这些人应该直接进入可以实际投掷的常规功能(灾难永远不要投掷)。在我看来,您担心的是没有任何真正意义的角案。
我想不出任何很好的解决方案来区分离开范围通常与有例外的范围。
检查stack_unwinding库 - 我在C 中实现了范围(失败)和范围(成功)功能。
它基于平台特定函数Uncuver_exception_count。它类似于标准库中的std :: Unduffe_exception,但取而代之的是返回未签名的int,显示了当前未被发现的例外计数。
目前已在{clang 3.2,GCC 3.4.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7,MSVC2005SP1,MSVC2008SP1,MSVC2010SP1,MSVC2012,MSVC2012}>
在C 11中有11种循环语法:
try
{
int some_var=1;
cout << "Case #1: stack unwinding" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
throw 1;
} catch(int){}
{
int some_var=1;
cout << "Case #2: normal exit" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
}
在C 98中,它更加嘈杂:
try
{
cout << "Case #1: stack unwinding" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
throw 1;
} catch(int){}
{
cout << "Case #2: normal exit" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
}
此外,库具有uminding_aware_destructor功能。示例:
struct DestructorInClass
{
UNWINDING_AWARE_DESTRUCTOR(DestructorInClass,unwinding)
{
cout << "DestructorInClass, unwinding: "
<< ( unwinding ? "true" : "false" ) << endl;
}
};
但是,在某些情况下,uminding_aware_destructor可能会给出错误的结果(尽管范围(成功)和范围(失败)功能不受此类问题的影响)。
- 分段故障(堆芯转储)矢量
- 为什么在全局范围内使用"extern int a"似乎不行?
- C++中的动态铸造故障
- 数组的指针从不分段故障
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- vscode g++链路故障:体系结构x86_64的未定义符号
- 在基于范围的for循环中使用结构化绑定声明
- 访问被拒绝后,c++中的故障保护代码
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 如何计算数据类型的范围,例如int
- 由于变量范围导致的段故障
- C 11中的范围(故障)
- Seg故障是由于试图访问超出范围的数组,原因不明
- 当流超出范围时偶尔出现SEG故障
- std::advance - 仅在调试时偏移超出范围的故障
- 分段析构函数中的超出范围故障
- 向量故障中的shared_ptr-迭代和丢失范围-获取损坏的数据