C++ 为什么会有';s没有混合-feexceptions和-fno异常的链接器警告

C++ 为什么会有';s没有混合-feexceptions和-fno异常的链接器警告,c++,gcc,clang,C++,Gcc,Clang,我感到惊讶的是,编译器链接器没有警告混合-fexceptions和-fno异常,或者特别是混合使用和不使用展开表的代码。我知道可能会有无限合法和/或无法控制的方式以这种状态结束,但我宁愿提前得到std::terminate(),而不是(接下来是无聊的测试设置): runner.cpp extern void testA(); int main() { try { testA(); } catch (...) {} } testA.cpp #include &l

我感到惊讶的是,编译器链接器没有警告混合-fexceptions和-fno异常,或者特别是混合使用和不使用展开表的代码。我知道可能会有无限合法和/或无法控制的方式以这种状态结束,但我宁愿提前得到std::terminate(),而不是(接下来是无聊的测试设置):

runner.cpp

extern void testA();

int main() {
    try {
        testA();
    } catch (...) {}
}
testA.cpp

#include <iostream>
extern void testB();

struct resA {
    ~resA() { std::cout << "release resA" << std::endl; }
};

void testA() {
    resA a;
    testB();
}
#包括
extern void testB();
结构研究所{

~resA(){std::cout某些ABI使展开表在某些情况下可选(通用)例如,叶函数不会更改堆栈指针,也不会关闭任何被调用方保存的寄存器。因此,链接带或不带展开表的代码不一定是错误。链接编辑器无法轻松确定是否缺少展开表,因为它们不是必需的,还是因为二进制文件未编译而缺少正确地说

此外,代码可以毫无例外地进行编译,但支持完全(甚至异步)这些表不仅被C++实现用于堆栈解卷,而且还通过调试和性能工具。在不必安装调试信息的情况下,获得精确的堆栈回溯提供了很大的价值,独立于编程语言或所使用的语言子集。这就是为什么这样做的原因。me GNU/Linux发行版以这种方式编译所有二进制文件(包括C程序),尽管会产生大小开销


但是你是对的,更好的工具链诊断是值得的。尝试收集许多关于推荐构建标志的检查,但它目前不包括展开信息。它检查
-feexceptions
,因为如果使用POSIX线程取消处理程序,即使是C代码也需要强化(未发生任何实际取消),原因是。但这里肯定有更好的诊断空间。这也是H.J.LU的GNU属性说明可以涵盖的内容。

一些ABI为某些情况(常见)提供了可选的展开表例如,叶函数不会更改堆栈指针,也不会关闭任何被调用方保存的寄存器。因此,链接带或不带展开表的代码不一定是错误。链接编辑器无法轻松确定是否缺少展开表,因为它们不是必需的,还是因为二进制文件未编译而缺少正确地说

此外,代码可以毫无例外地进行编译,但支持完全(甚至异步)这些表不仅被C++实现用于堆栈解卷,而且还通过调试和性能工具。在不必安装调试信息的情况下,获得精确的堆栈回溯提供了很大的价值,独立于编程语言或所使用的语言子集。这就是为什么这样做的原因。me GNU/Linux发行版以这种方式编译所有二进制文件(包括C程序),尽管会产生大小开销


但是你是对的,更好的工具链诊断是值得的。尝试收集许多关于推荐构建标志的检查,但它目前不包括展开信息。它检查
-feexceptions
,因为如果使用POSIX线程取消处理程序,即使是C代码也需要强化(未发生任何实际取消)但是,这是H.J.Lu的GNU属性注释可以覆盖的地方。

我确信链接器不知道,也不负责那种管道。这里的真正问题是如果编译器被编译来编译C++代码而不支持异常,则COMP。伊勒应该说“哈哈,呜呜?”,而不是生成损坏的代码。我用gcc尝试了这个实验。它似乎悄悄地接受了-fno exceptions参数,并悄悄地忽略了它。至少最终结果是来自两个析构函数的消息。@SamVarshavchik不确定我是否遵循了您的答案,或者您是否复制了我的设置?编译器在这个测试中应该非常满意:代码不抛出的代码是编译时没有异常的,而代码是有异常的exceptions@SamVarshavchik你是什么意思?没有支持异常的情况下,生成C++代码的原因是无穷的。@ SavaVaveCK是的,为什么?就像我说的,这是经常发生的,例如,嵌入式开发,所以我认为你过于泛化了。在GCC中,没有例外是有原因的,它是可用的。我很确定链接器不知道,也不负责那种管道。这里真正的问题是,如果编译器被定向编译C++代码而不支持异常,编译器应该去“LOL!WUT?”,而不是生成损坏的代码。我用gcc尝试了这个实验。它似乎悄悄地接受了-fno exceptions参数,并悄悄地忽略了它。至少最终结果是来自两个析构函数的消息。@SamVarshavchik不确定我是否遵循了您的答案,或者您是否复制了我的设置?编译器在这个测试中应该非常满意:代码不抛出的代码是编译时没有异常的,而代码是有异常的exceptions@SamVarshavchik你是什么意思?没有支持异常的情况下,生成C++代码的原因是无穷的。@ SavaVaveCK是的,为什么?就像我说的,这是经常发生的,例如,嵌入式开发,所以我认为你过于泛化了。gcc中没有任何例外是有原因的,并且它是可用的。
#include <iostream>
struct resB {
    ~resB() { std::cout << "release resB" << std::endl; }
};

void testB() {
    resB b;
    throw 42;
}