具体而言,我想知道GCC在使用-fno-exceptions
编译的代码链接时如何保证抛出异常行为的代码(如果有的话)。
GNU libstdc++
手册说明了以下here。
在详细说明
-fno-exceptions
的库支持之前,首先要记下使用此标志时丢失的内容:它会破坏尝试通过-fno-exceptions
编译的代码的异常,无论代码是否有任何try
或catch
结构。如果您可能有一些代码抛出,则不应使用-fno-exceptions
。如果您有一些使用try
或catch
的代码,则不应使用-fno-exceptions
。
这听起来像是一句话,"你不应该......#34;即未定义的行为。
另一方面,我对this SO question的印象是,只要使用-fno-exceptions
编译的代码不是throw
,try
,所有内容都是犹太的,或catch
(显然是编译时错误),异常从不通过此库中的函数传播。这是有道理的:为什么编辑用-fno-exceptions
编译的图书馆是否会抛出异常,只要他们不与其功能互动?
我做了一点修改,发现如果我使用GCC 7.1.1编译一个简单的程序,其中一个源文件用-fno-exceptions
编译而另一个抛出并捕获异常,那么一切都编译,链接和运行正常。但这并不意味着这种行为得到保证;它仍然可能是未定义的。
我所有这一切的动机是,我有一种情况,我将我自己的应用程序代码与使用-fno-exceptions
构建的库相关联,并且根据对所述库进行的函数调用,在我自己的代码中抛出异常会导致立即的段错误,即使该异常没有通过库的函数传播。它对我来说闻起来像库中的一个错误,但我想也许在编译期间传递-fno-exceptions
时允许这样做。
海湾合作委员会actual reference on code-generation flags提到-fexceptions
相对简短,并没有回答我的问题。有人知道另一个参考/有相关经验吗?
更新:我从源重建了库,这次启用了异常支持。段错仍然存在!错误报告的时间。
答案 0 :(得分:2)
正如链接问题所指出的那样,GCC 需要以允许-fno-exceptions
和-fexceptions
共存,以便链接C和C ++。
在更理论的层面上,异常问题与程序的调用图密切相关。这是有向图(调用者/被调用者),但它可以是循环的,并且节点之间可以有多个边。现在可以使用或不使用异常编译每个函数/节点。我们可以将安全程序定义为一个程序,其中“无例外”节点不能从“无例外”节点到达。
这可能是不必要的严格 - try...catch(...) { }
块中的C ++位代码应该可以从C代码调用,这似乎是合理的。但我不知道海湾合作委员会的保证。并考虑它的含义 - 调用图与调用堆栈有关。调用堆栈通常形成从main()
到当前正在执行的函数的路径。如果整个路径都是异常感知的,则异常是安全的。但是如果有一个函数不知道异常,它可能会使堆栈处于无法安全处理异常的状态,甚至如果堆栈展开不会放松那么远。