gpt4 book ai didi

c++ - 在混合 C 和 C++ 代码编程中捕获异常后对象未被销毁

转载 作者:太空狗 更新时间:2023-10-29 20:20:26 24 4
gpt4 key购买 nike

我正在编写一个混合使用 c 和 c++ 的程序,我遇到了一个关于 c++ 异常处理程序中对象销毁的问题。我写了一个简单的案例来重现这个问题。

main.cpp

#include <iostream>

extern "C" void test(void(*f)(void));

struct foo {
~foo() {
std::cout << "foo destruction" << std::endl;
}
};

void error_handler(void) {
throw 1;
}

int main() {
try {
foo f;
test(error_handler);
} catch (...) {

}
}

测试.c

void test(void(*handler)(void)) {
handler();
}

当我在 Visual Studio 2015 和 Visual Studio 2017 中构建它时,未调用 foo 的析构函数。但是当我使用 gcc 5.4 测试它时,foo 的析构函数工作正常。

是否可以通过调用函数指针(指向cpp代码中实现的函数的指针)在C代码中抛出C++异常?上面的代码是非法的还是只是一个 msvc 错误?

最佳答案

Windows 异常机制被明确设计为能够运行析构函数并执行最终类型清理,即使存在异常和来自其他语言的类似情况也是如此。

所以您所要求的应该在 Windows 上正常工作 - 它的设计目的是什么。

但是,您需要在 Visual Studio 中明确启用它。默认情况下,visual studio 使用 /EHsc 异常模型设置 C++ 代码,该模型明确假定 extern "C" 函数不抛出或传递异常。这是一个优化,通常是一个很好的优化。

但是,如果您需要假设 extern "C" 函数会抛出或传递异常,那么您需要更改异常模型。您可能需要 /EHs

但是,我建议您在更改它之前阅读它的后果 here .

编辑:是否使用此功能值得商榷。通常,对于异常(和其他类似机制),抛出者和调用者之间堆栈上的所有代码都需要是异常安全的。如果您拥有代码,那么这很好,如果堆栈中有 Windows 回调或其他库之类的东西,那么您需要找到一个保证,这没问题。一般为 windows internal code它不是。

关于c++ - 在混合 C 和 C++ 代码编程中捕获异常后对象未被销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51206207/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com