可以标记为Extern"C"的C++函数抛出吗?

Wil*_*ode 25 c++ extern-c

我有C++函数我想要声明使用,extern "C"即使它们只在C++代码中调用.是的,我知道这很奇怪但是我想要保持一致性,因为我们混合了C和C++声明.我只是想确保声明一个C++函数extern "C"不会影响抛出的行为.

它看起来像这样:

extern "C" void foo() {throw exception;}

int bar()
{
    try
    {
        foo();
    } catch (exception e) { return 1; }
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*nst 10

"可以将C++函数标记为Extern"C"抛出吗?"

是的,从某种意义上说语言和编译器都不会阻止你这样做.

,从某种意义上说,如果你抛出,它将是一个未定义的行为,因为C++异常跨越了语言边界.

在实践中:不要这样做.捕获异常并将其转换为错误代码,或者其他语言可以理解的方式.

所以底线是:不要从标记为的函数中抛出异常extern "C".

  • 当它的"未定义的行为"时,你不能说"是".当您调用"未定义的行为"时,您的代码基本上已被破坏. (4认同)
  • @LokiAstari,问他们可以抛出问题,答案是肯定的.如果直接从具有c ++链接的函数调用extern"C"函数,则没有未定义的行为.从C调用的相同函数,未定义的行为.由于联系,不一定有语言交叉,但它肯定是一种气味. (4认同)
  • 我必须同意@LokiAstari.在我的代码中,我让C++调用一个抛出异常的`extern c`函数,并且*没有被捕获*(即使使用`catch(...)`).编译器是Intel编译器(icpc).所有代码都是用C++编写的,没有C.链接差异似乎足以打破堆栈展开. (4认同)
  • @LokiAstari,我必须对你的陈述采取例外,"你的'未定义的行为'时,你不能说'是'." "未定义的行为"对于是否可以或应该发生并不重要.它仅指定结果未定义.它没有指明它永远不会发生.跨越边界的例外情况一直在发生.C++ - > C.; C++ - >的Java; C++ - >的Python.不同的是,大多数语言翻译库提供了将异常捕获,翻译和重新抛出到目标语言的工具. (2认同)
  • 你的第一个假设是错误的:`如果直接从具有c ++连接的函数调用extern"C"函数.如果它抛出未定义的行为.C函数的ABI不包含允许堆栈展开所需的信息. (2认同)

Mar*_* Ba 6

GCC来说,答案似乎没有定论.

然而,MSVC文档在这个主题上相对清楚:

  • /EHa/EHs... 告诉编译器假设声明为extern"C"的函数可能会抛出异常.
  • /EHsc... 告诉编译器假设声明为extern"C"的函数从不抛出C++异常

因此,对于Visual-C++,它是否依赖于编译器选项是否获得定义的行为.