代码之家  ›  专栏  ›  技术社区  ›  Oystein

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

  •  5
  • Oystein  · 技术社区  · 16 年前

    我听说在C/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; 
    }
    

    这样安全吗?

    4 回复  |  直到 16 年前
        1
  •  3
  •   Artyom    16 年前

    尤其是如果调用代码和库是用不同的编译器编译的

    通常不能混合不兼容ABI的不同C++编译器。因此,例如,不能从用MSVC编译的库中抛出异常并尝试捕获 它与海湾合作委员会。

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

    小音符:

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

        2
  •  3
  •   Void - Othman    16 年前

    对于gcc,至少有一种情况下,从gcc生成的共享库捕获异常是有问题的,即当忘记导出 throw 当符号可见性为“时,共享库中的表类型” hidden “默认情况下。这个 GCC Visibility Wiki 页面详细介绍了这个问题以及如何防止它发生。

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

        3
  •  1
  •   Frank Osterfeld    16 年前

    当涉及到DLL和异常时,一般都会理解:

    不要在头中内联实现异常类。您将得到重复的vtables和rtti信息,从而导致使用代码中未捕获异常(由于重复,该异常被认为是另一种类型)。

    细节:

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

        4
  •  0
  •   carribus    16 年前

    您给出的示例应该可以很好地工作,但是对于DLL,如果您碰巧抛出了一个堆分配的异常,那么如果DLL的使用者试图释放堆分配的异常,您将崩溃。

    推荐文章