以编程方式确定是否启用了异常 大多数C++编译器允许禁用异常。有没有一种方法可以在不使用特定于编译器的预处理器宏(例如MSVC的_cppundwind)的情况下从代码中确定它?在编译时,

以编程方式确定是否启用了异常 大多数C++编译器允许禁用异常。有没有一种方法可以在不使用特定于编译器的预处理器宏(例如MSVC的_cppundwind)的情况下从代码中确定它?在编译时,,c++,exception,metaprogramming,C++,Exception,Metaprogramming,不。异常是C++的一部分。事实上,某些编译器允许您禁用它们是完全不相关的,标准不会为您提供检测它们是否已启用的功能—就其而言,它们始终处于启用状态。如果您想了解特定于实现的行为,唯一的方法就是询问实现。我根本不会让运行时承担这个决定的负担。相反,我将构建两个库: libfoo.a libfoo_exc.a 然后让我的配置脚本确定是否存在异常,并将生成文件设置为: ifeq($HAVE_EXCEPTIONS, 1) foolib=foo_exc else foolib=foo endif

不。异常是C++的一部分。事实上,某些编译器允许您禁用它们是完全不相关的,标准不会为您提供检测它们是否已启用的功能—就其而言,它们始终处于启用状态。如果您想了解特定于实现的行为,唯一的方法就是询问实现。

我根本不会让运行时承担这个决定的负担。相反,我将构建两个库:

libfoo.a
libfoo_exc.a
然后让我的
配置
脚本确定是否存在异常,并将生成文件设置为:

ifeq($HAVE_EXCEPTIONS, 1)
  foolib=foo_exc
else
  foolib=foo
endif

libs=$(libs) -l$(foolib)

$(TARGET): $(OBJECTS)
    $(CXX) -o $(TARGET) $(OBJECTS) $(LDFLAGS) $(LIBS)
要确定是否存在异常,您可以简单地尝试使用注释中建议的一个简单的try/catch块构建一个小型测试程序

要实际构建库,只需编写条件代码:

#if HAVE_EXCEPTIONS > 0
/* ... */
#else
/* ... */
#endif
然后构建两个库,一个包含
-DHAVE_EXCEPTIONS=0
,另一个包含
-DHAVE_EXCEPTIONS=1
或类似内容

这样,您就没有运行时开销,您的客户机可以使用他们喜欢的任何库。

因为,有一个建议使用的宏

__cpp_exceptions

如果支持异常并且编译器符合C++98,则其值为199711。其他。

如果这是一个autoconf系统,只需让autoconf尝试用
try
/
catch
编译一些东西,看看它是否会编译。Visual Studio?不确定,您可能被宏卡住了。有趣的问题,但这些信息有什么用?很难理解这一点。不管是否启用异常处理,bad_alloc和friends都是真实的。“让我们做一些合理的事情”的角度毫无例外是一个非常模糊的角度。他们以这样或那样的方式轰炸你的程序。@Hans:允许异常“轰炸你的程序”在许多情况下都是可以接受的风险。例如,99%的视频游戏禁用异常以提高性能。@Kerrek SB:我正在寻找重新设计一个库的好方法,该库既可用于启用异常的项目,也可用于禁用异常的项目。Boost有自己的宏用于此目的-我正在寻找避免预处理器的东西。+1。这似乎是OP的问题,如果一开始就有缺陷。它可以被重新表述为:“我能以编译器不可知的方式检测特定于编译器的行为吗?”@Andre:你可以自由地重新表述它,但我相信我在问一个具体而实际的问题。我观察到的一个挑战是MSVC不使用这些&如果禁用异常/rtti,那么这些宏是未定义的,很难区分这两个(即,编译器是否支持_cpp_异常&异常被禁用,或者编译器是否不支持_cpp_异常&我们应该使用编译器特定的逻辑)。