专注于VisualC++,您在使用throw() (即__declspec(nothrow))非抛出规范的C++代码中是否经历过显著的性能提高?它真的对优化器有帮助吗?是否有显示性能提高的基准?
我在互联网上发现了不同的(相反的)建议:
Boost异常.规范原理反对throw(),而Larry似乎在他的博客文章为什么要在方法中添加抛出()?中表示支持
(我想澄清的是,我对VC++特定的代码感兴趣;我知道在GCC中,由于运行时检查,throw()规范实际上可能是一个“悲观”。)
P.S.读取ATL,我发现throw()被广泛使用;此外,我在这篇MSDN文章中找到了一个使用throw()规范的方便的C++ RAII unique_handle类。
发布于 2012-05-12 09:49:38
MSVC编译器将其视为优化提示,是的。
Boost必须是跨平台的,他们必须在各种编译器上实现安全和高效的功能。正如Boost文档所述,当指定throw()时,一些编译器可能会生成较慢的代码,而且在许多情况下,编译器可以推断出,不管是否有throw()规范,都不会抛出异常,因此对于boost来说,最安全的方法就是永远不要使用抛出规范。
但是如果您是专门针对MSVC的,那么throw()有效地告诉编译器不要为函数生成异常处理代码,如果函数太复杂,编译器无法确定不能抛出异常,这可能会加快速度。
发布于 2012-05-12 08:08:44
我添加了它,但它并不能帮助优化器its帮助我编写更正确的代码。
class X
{
public:
void swap(X& rhs) throw(); // Swap better not ever throw
// If it does there is something else
// much more seriously wrong
};发布于 2012-05-12 10:26:23
throw()的主要问题是标记为throw()的函数内部的代码可以抛出。例如,这将完美地工作:
void foo() throw()
{
throw "haha\n";
}
int main()
{
try {
foo();
}
catch(const char* s) {
std::cout << s;
}
return 0;
}请注意,当然foo不会throw到main。并且不会捕获异常(就像注释throw()说明符一样)。相反,编译器将用try{}catch()块包装代码函数。当异常生成时,它将由全局处理程序处理(这意味着程序默认崩溃)。
注意,编译器必须用try{}cath()块包装函数代码,除非编译器确信内部代码不可能生成异常。
因此,可以对foo的调用方进行一些优化,但是foo内部的情况会变得更加复杂。
编辑:
__declspec(nothrow)的不同之处在于:作为Microsft,
这个属性告诉编译器,声明的函数和它调用的函数从不抛出异常。
这意味着编译器可以省略try{}catch()包装器代码。
EDIT2实际上,微软违反了标准行为,不为throw()生成整容器。那么您可以使用throw()来提高性能。
https://stackoverflow.com/questions/10559521
复制相似问题