我一直看到有人说异常很慢,但我从来没有看到任何证据.因此,我不会询问它们是否存在,而是会询问异常是如何在场景背后起作用的,因此我可以决定何时使用它们以及它们是否很慢.
据我所知,异常与做一堆返回是一回事,但它也会检查何时需要停止返回.它如何检查何时停止?我正在猜测并说有一个第二个堆栈,其中包含异常类型和堆栈位置然后返回直到它到达那里.我也猜测堆栈触摸的唯一时间是抛出和每次尝试/捕获.使用返回代码实现类似行为的AFAICT将花费相同的时间.但这都是猜测,所以我想知道.
例外如何真正起作用?
我无法找到迫使与申报功能标准的东西extern "C"是noexcept,无论是含蓄或明确.
但是,应该很清楚C调用约定不能支持异常......或者是它?
标准是否提到了这个,我错过了某个地方?如果没有,为什么不呢?它只是作为各种实现细节留下的吗?
抛出对象后,gcc,clang和VS2015不会在下面的代码中忽略对move构造函数的调用a.在我看来,满足§8.12[class.copy]/31(N4140)的项目符号(31.2)中确定的条件.
#include <iostream>
struct A
{
A() { std::cout << "Default ctor " << '\n'; }
A(const A& a) { std::cout << "Copy ctor" << '\n'; }
A(A&& a) { std::cout << "Move ctor" << '\n'; }
~A() { std::cout << "Destructor " << '\n'; }
};
int main()
{
try
{
A a;
throw a;
}
catch(A& a) { std::cout << "Caught" << '\n'; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,这a是一个左值,但根据§12.8/ 32,首先执行重载决策以选择副本的构造函数,就像对象由rvalue指定一样.也就是说,对move构造函数的调用是可以的.如果删除上面的移动构造函数的定义,则调用复制构造函数,但同样,它不会被省略!
我理解标准没有规定复制省略,但我很想知道是否有任何特殊条件可以证明这一事实,上面提到的三个编译器在这个特定的例子中避免了这种优化.
gcc的示例输出,来自上面的链接:
g ++ -std …
假设我有一个用c ++实现的共享库,但是暴露了一个纯c接口.然后该库用于ac程序.
如果异常从c ++库转移到c应用程序中,gcc是否会对发生的情况做出任何保证?
它会不会总是终止程序?
我主要对Linux on x64和ARMv7-R上的gcc答案感兴趣,但也欢迎其他操作系统,编译器和架构的答案.
编辑:
只是为了明确这一点:我不是在讨论让异常通过c函数然后被调用c ++函数或与c或c ++回调交互.应用程序代码本身就是纯粹的c.在某些时候,它将调用共享库的一个函数(内部是纯c ++),并且在该函数返回之前不会调用任何应用程序代码.另外,我们假设我无法控制用于编译应用程序代码的标志.
有这个代码:
char text[] = "zim";
int x = 777;
Run Code Online (Sandbox Code Playgroud)
如果我查看放置x和文本的堆栈,那么输出是:
09 03 00 00 7a 69 6d 00
Run Code Online (Sandbox Code Playgroud)
哪里:
现在有try..catch的代码:
char text[] = "zim";
try{
int x = 777;
}
catch(int){
}
Run Code Online (Sandbox Code Playgroud)
堆:
09 03 00 00 **97 85 04 08** 7a 69 6d 00
Run Code Online (Sandbox Code Playgroud)
现在text和x之间放置了新的4字节值.如果我添加另一个捕获,那么会有类似的东西:
09 03 00 00 **97 85 04 …Run Code Online (Sandbox Code Playgroud) 如果我执行以下操作,运行时如何确定抛出异常的类型?它是否使用RTTI?
try
{
dostuff(); // throws something
}
catch(int e)
{
// ..
}
catch (const char * e)
{
// ..
}
catch (const myexceptiontype * e)
{
// ..
}
catch (myexceptiontype e) // is this the same as the previous handler?
{
// ..
}
Run Code Online (Sandbox Code Playgroud)
考虑C库中定义的以下函数:
void f(void (*callback)(int)) { callback(0); }
Run Code Online (Sandbox Code Playgroud)
这将从C++ 11程序中调用callback(),可能会引发异常,如下所示:
void callback(int) { /* can I throw ? */}
try {
f(callback);
} catch (...) {
/* can the exception be caught ? */
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
f()?如果没有,我必须/应该callback()用说明noexcept符声明吗?