我能否在STL中禁用异常?

21
我想在使用MSVC编译的C++应用程序中禁用异常。我已将选项“启用C++异常”切换为NO,但仍收到警告提示我使用选项/Ehsc,而我不想使用它。
我的代码中没有try/catch块,但我使用STL。我发现使用宏定义_HAS_EXCEPTIONS=0应该可以禁用STL中的异常,但我仍然收到警告,例如:
警告 C4275:非dll接口类“stdext::exception”被作为dll接口类“std::bad_typeid”的基类使用 请参见“stdext::exception”的声明 请参见“std::bad_typeid”的声明
有没有办法关闭STL中的异常?
注意:在我的代码中,我也想关闭RTTI选项。无论RTTI开启或关闭,我都会得到同样的警告。

https://dev59.com/hKfja4cB1Zd3GeqP0Ltf#65513682 - Chef Gladiator
3个回答

10

Microsoft STL支持异常停用。

对于MSVC STL,定义宏_HAS_EXCEPTIONS=0将在你使用libcmt.lib/libcmtd.lib(/MT或/MTd编译器选项)链接应用程序时禁用异常。

如果你使用msvcrt.lib/msvcrtd.lib(/MD或/MDd编译器选项)链接,则需要定义另一个宏——_STATIC_CPPLIB。在这种情况下,在包含任何STL代码之前,请添加以下行:

#define _HAS_EXCEPTIONS 0
#define _STATIC_CPPLIB

或者将以下内容添加到编译器选项:

-D_HAS_EXCEPTIONS=0 -D_STATIC_CPPLIB
请注意,您需要在项目设置中禁用C++异常。

2
我不理解的是,在使用/MD或/MDd时,为什么我们需要_STATIC_CPPLIB。从我所能阅读的内容来看,它会导致代码使用libcmt.lib而不是msvcrtd.lib。使用/MD的整个目的是使用动态链接库而不是静态链接库。添加_STATIC_CPPLIB似乎会破坏使用/MD标志的目的。 - gnash117
_STATIC_CPPLIB在MSVC 2010中已被弃用,因此在MSVC 2010中使用它只会将一个警告集替换为另一个警告集。 - gnash117
gnash117,MSDN针对MSVC2008的说明称,当使用_STATIC_CPPLIB预处理器定义时,您的应用程序将链接到libcmt.lib而不是msvcprt.lib,但仍通过msvcrt.lib动态链接到主CRT。 - Rom098
如果STL容器没有足够的内存,会发生什么呢?例如,它会崩溃吗? - sasha.sochka
通常情况下,如果不使用异常,STL应用程序只会调用terminate()。对于这种情况,我们需要使用另一种方式来处理STL错误,例如https://dev59.com/tlDTa4cB1Zd3GeqPNfPP。 - Rom098
@sasha.sochka https://dev59.com/hKfja4cB1Zd3GeqP0Ltf#65513682 - Chef Gladiator

7
您需要使用支持异常停用的STL。通常这是一个编译时宏定义。
除非我错了,STLPort提供了_STLP_USE_EXCEPTIONS=0和_STLP_NO_EXCEPTIONS。我不知道这些设置下程序的行为如何。 ;)
我认为MS STL中也有一些隐藏标志。
EASTL默认禁用异常。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html


6

type id 与运行时类型识别有关。您可能还想尝试关闭 RTTI。

然而,C++ 标准库的某些部分被指定为引发异常。如果禁用它们,您就会陷入“未定义行为”的污浊水域。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接