我感兴趣的是这是否是标准强制的,是否被某个编译器违反了。我的观察是:
>
gcc(6.3.0)中,throw()函数中的堆栈被解除,但随后调用std::terminate(try/catch不能cought异常)。但是在7.0(当前HEAD)中,没有堆栈被释放,将立即调用std::Termiante。实际上,gcc 7.0甚至对此发出警告:warning:throw将始终调用terminate()[-wterminate]
forNOExceptFunctionWithObj2()
。它使throw()表现为noext(true)。
clang,在我检查过的所有版本中,展开函数堆栈(调用对象d-tors),然后调用std::Terminate。
#include <iostream>
#include <string>
#include <vector>
struct TestDataWithoutNoexcept {
TestDataWithoutNoexcept() {
std::cout << __FUNCTION__ << "\n";
}
~TestDataWithoutNoexcept() {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept(TestDataWithoutNoexcept const & rhs) {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept(TestDataWithoutNoexcept && rhs) {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept& operator=(TestDataWithoutNoexcept const& rhs) {
std::cout << __FUNCTION__ << "\n";
}
};
void NoExceptFunctionWithObj1() noexcept {
TestDataWithoutNoexcept test;
throw std::runtime_error("NoExceptFunctionWithObj1 ex.");
}
void NoExceptFunctionWithObj2() throw() {
TestDataWithoutNoexcept test;
throw std::runtime_error("NoExceptFunctionWithObj2 ex.");
}
int main()
{
// Now lets see whether stack is being unwound when exception is thrown in noexcept versus throw() function.
std::cout << "\n See how dtors are called in noexcept or throw() functions\n";
try {
//NoExceptFunctionWithObj1();
}
catch (std::runtime_error& ex) {
std::cout << ex.what();
}
try {
NoExceptFunctionWithObj2();
}
catch (std::runtime_error& ex) {
std::cout << "\nShouldn't this be shown? : " << ex.what();
}
}
是,应调用std::Terminate
。最新公布的标准草案称:
15.4[例外规定],第12段
如果异常规范的形式为throw()、noexcept或noexcept(constant-expression),其中constant-expression,其中constant-expression),则异常规范是非抛出的。
当搜索一个处理程序(15.3)遇到一个函数的最外层块,该函数的noexcept-specification不允许出现异常(15.4)[...]std::Terminate()被调用(18.8.3)。在没有找到匹配处理程序的情况下,在调用std::terminate()之前是否展开堆栈是由实现定义的
不调用std::terminate
表示MSVC不兼容。
关于堆栈的处理,在您的示例中,编译器执行它想要的关于是否展开堆栈的操作--这被指定为实现定义的。
问题内容: 我的第一个问题是- 构造函数应始终声明为公共吗? 如果我创建一个构造函数该怎么办。 我总是看到构造函数是隐式的。那么为什么构造函数有用呢?还是根本没有用。因为没有人可以调用它,或者永远也不能创建对象(由于构造函数)!这是我的第二个问题。 问题答案: 不, 构造函数 可以是,, 或(根本没有访问修饰符)。 做某事 并不意味着没有人可以访问它。这只是意味着该类之外的任何人都不能访问它。因此
这对我来说很奇怪。继承自,后者继承自。 但是 还有,这有点企业设计的味道。不同的程序员或团队可以添加回调来处理该项,但它们应该相互隔离。这意味着,作为负责将这些回调相互隔离的程序员,我不应该依赖它们来确保错误不会溜走。捕捉应该是正确的,但这并不是因为会漏过。所以我更普遍的问题是:这里什么是好的模式?只是,我认为这是由于继承导致的语法错误?
在 C 中实现回调函数时,我是否仍应使用 C 样式函数指针: 或者我应该使用std::函数:
我使用mysql C++connector和这段(稍微简化了一点)代码。 连接器应该抛出SQL::SqlException,它派生自std::Exception并具有一些附加方法,如。 抛出的异常在第二个块中捕获,但可以成功转换为(并用作)。 更奇怪的是,不同可执行文件中的类似代码会像预期的那样捕获。它们之间的区别在于,第一个是在一个共享对象(.so)中,该对象加载了。
问题内容: 我只知道非基元(对象)放在堆上,方法在堆栈上,但是基元变量呢? -更新 根据答案,我可以说堆可以有一个新的堆,并且给定对象可以堆吗?假设对象将具有基本变量和引用变量。 问题答案: 本地定义的基元将在堆栈中。但是,如果将原语定义为对象实例的一部分,则该原语将位于堆上。 关于更新: 对象没有自己的堆栈。在我的示例中,实际上是的每个实例的一部分。只要分配了HeapClass的实例(例如),就