繁体   English   中英

从静态链接的C ++库中抛出异常是不安全的?

[英]Unsafe to throw exceptions from statically linked C++ libraries?

我听说在C ++库中抛出异常可能是有危险的,特别是对于DLL,特别是如果调用代码和库是用不同的编译器编译的。 有没有道理呢? 只要我坚持使用静态库,它是否安全? 请注意,我不是只讨论库中异常的内部使用,我想将它们深入到调用代码中:)

只是为了澄清:假设我有一个编译的静态库,它定义了类Foo:

class Foo
{
public:
    // Constructor
    Foo()
    {
        /* ... Do stuff ... */        
        if (stuffwentwrong)
            throw(123); // We throw an integer error code (to make it simple) 
    }
};

有些人像这样使用它:

try 
{
    Foo foo_object;
}
catch (int i)
{
    std::cout << "Oh bum. Code: " << i; 
}

那会安全吗?

特别是如果调用代码和库是用不同的编译器编译的

您通常不能混合使用不兼容ABI的不同C ++编译器。 因此,例如,您不能从使用MSVC编译的库中抛出异常并尝试使用GCC捕获它。

但除此之外,你通常没有问题。

小记:

MSVC有几个不兼容的异常模型,不要混用它们。

关于GCC,至少有一种情况是从GCC生成的共享库中捕获异常可能会有问题,即在默认情况下“ hidden ”符号可见性时忘记从共享库中导出throw类型时。 GCC Visibility Wiki页面详细介绍了该问题以及如何预防该问题。

我不确定Windows DLL是否有类似的问题,但似乎很可能。

关于DLL和异常的常见问题:

不要在标头中实现内联的例外类。 最终会出现重复的vtable和RTTI信息,导致使用代码中没有捕获异常(由于重复,异常被认为是另一种类型)。

细节:

http://marcmutz.wordpress.com/2010/08/04/fun-with-exceptions/

您提供的示例应该可以正常工作,但是对于DLL,如果碰巧抛出堆分配的异常,如果DLL的使用者尝试释放堆分配的异常,则会崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM