【发布时间】:2018-02-06 17:24:56
【问题描述】:
具体来说,我想知道 GCC 对抛出异常的代码在链接到使用 -fno-exceptions 编译的代码时的行为做出了哪些保证(如果有的话)。
GNU libstdc++ 手册说以下here。
在详细说明库对
-fno-exceptions的支持之前,首先要说明一下使用此标志时丢失的内容:无论该代码是否有任何@987654328,它都会破坏尝试通过使用-fno-exceptions编译的代码的异常@ 或catch构造。如果你可能有一些抛出的代码,你不应该使用-fno-exceptions。如果您的某些代码使用了try或catch,则不应使用-fno-exceptions。
这听起来像是“你不应该......”的声明,即未定义的行为。
另一方面,我对this SO question 的印象是,只要使用-fno-exceptions 编译的代码不是throw、try 或catch(显然是编译时错误)和异常永远不会通过这个库中的函数传播。这是有道理的:为什么使用-fno-exceptions 编译的库要关心是否抛出异常,只要它们不与其函数交互?
我做了一些修改,发现如果我使用 GCC 7.1.1 编译一个简单的程序,其中一个源文件使用 -fno-exceptions 编译,另一个抛出并捕获异常,一切都可以编译、链接并运行良好.但这并不意味着这种行为是有保证的;它可能仍然是未定义的。
我在这一切中的动机是我有一种情况,我将自己的应用程序代码与使用-fno-exceptions 构建的库链接,并且根据对所述库进行的函数调用,在即使该异常没有通过库的函数传播,我自己的代码也会立即导致段错误。对我来说,这闻起来像是库中的错误,但我认为在编译期间传递 -fno-exceptions 时,这可能是允许的。
GCC 的actual reference on code-generation flags 相对简短地提到了-fexceptions,并没有回答我的问题。有人知道其他参考/有相关经验吗?
更新:我从源代码重建了库,这次启用了异常支持。段错误仍然存在!是时候报告错误了。
【问题讨论】:
-
我会说您认为没有明确声明
-fno-exceptions和-fexceptions兼容但这是隐含的是正确的。但是(这是一个疯狂的点)你确定当你抛出异常时你没有通过任何库代码。可能发生的明显“隐藏”方式是在堆栈展开时调用(或未调用或未调用)-fno-exceptions析构函数。只是一个想法。 -
我不认为这就是我的情况,因为即使我将
throw直接放入try/catch中的main作为测试,仍然会发生段错误.它永远不允许传播到足以触发任何析构函数。不过,当我读到你的建议时,我只是做了一个双重考虑。我当然没有想到这种可能性! -
不客气。只是向你抛出想法。我对 gcc 不太熟悉,当然也不是更奇特的配置。文档肯定读起来像“这里有一堆半途而废的东西来做禁用异常的非常糟糕的事情。警告购买者”。
标签: c++ exception gcc segmentation-fault compiler-flags