【发布时间】:2013-04-06 00:31:09
【问题描述】:
我有想要使用extern "C" 声明的 C++ 函数,即使它们只在 C++ 代码中调用。是的,我知道这很奇怪,但为了保持一致性,我想这样做,因为我们混合了 C 和 C++ 声明。我只是想确保将 C++ 函数声明为 extern "C" 不会影响抛出的行为。
看起来像这样:
extern "C" void foo() {throw exception;}
int bar()
{
try
{
foo();
} catch (exception e) { return 1; }
}
【问题讨论】:
-
答案断言,如果异常从 C++ 代码抛出到实际的 C 代码(不知道如何处理异常),则您正在调用未定义的行为。我认为这是正确的,但是您是在问从 C++ 还是从 C 调用
extern "C"函数?如果您从 C++ 调用它们(而不是从 C 调用),那么不可避免的问题是“如果函数从未从另一种语言调用,为什么是函数extern "C"?”,但我认为只需使用 @987654327 调用 C++ 函数来自 C++ 的 @ 表示没有跨越语言边界,因此没有未定义的行为。 -
感谢所有为回答此问题做出贡献的人。如果我理解正确,我的问题的最终答案是:extern "C" 不会改变处理异常的方式。但是,抛出未被捕获并跨越语言边界的异常具有未定义的行为。
-
q:"extern "C" 不会改变处理异常的方式"——我不会那样阅读答案。具体
/EHsc另有说法。 -
@JonathanLeffler 每个编译器版本的 cpp 都是另一种语言。如果您有一个 msvc 静态库,除非它是使用 extern "C" 的 C 库,否则它将无法与 GCC 一起使用。每个编译器都可以根据他们的感觉来修改名称,因此当引用实际存在时,您最终会得到未定义的引用。我认为并且看不到任何不应该标准化名称修改的理由;但这是仅将 extern "C" 用于 C++ 的常见原因。例如,我必须创建 dll 以在 gcc 中使用来自 msvc 的代码,因为该代码需要 msvc 特定的东西。然后我必须使用 extern "C" 来抑制名称修改。