Does the C++ standard mandate that C-linkage functions are `noexcept`?

泪湿孤枕 提交于 2019-12-03 04:34:57

As far as I can tell there is no guarantee that function defined with "C" linkage will not throw exceptions. The standard allows a C++ program both to call an external function with "C" language linkage, and to define functions written in C++ that have "C" language linkage. Therefore there is nothing to prevent a C++ program from calling a function with "C" language linkage that is actually written in C++ (in another compilation unit maybe, although even this is not necessary). It would be a strange thing to do, but it is hard to rule out. Also I don't see where in the standard it says that doing so would lead to undefined behavior (in fact since the Standard cannot define the bahavior of function not written in C++, this would be the only usage where there is not formally undefined behavior).

As a consequence I think it would be an error to assume that "C" linkage implies noexcept.

Um, I assume extern "C" just use C-linkage, not C function. It prevents the compiler from doing C++ name mangling.

More directly - Suppose this code.

// foo.cpp
extern "C" void foo()
{
    throw 1;
}

// bar.cpp
extern "C" void foo();
void bar()
{
    try
    {
        foo();
    }
    catch (int)
    {
        // yeah!
    }
}

There is nothing anywhere that says that extern "C" functions are noexcept. On the other hand, almost all C standard library functions are noexcept unless you do something strange. Typically, this boils down to invoking undefined behavior, but there are a few other cases. These should be all of them:

  • The function pointer argument to qsort() can throw; therefore qsort() can throw.
  • The same is true of bsearch().
  • You are allowed to replace malloc(), realloc(), and free(). If you do, these may throw.
  • In the previous case, calloc(), fopen(), fclose(), freopen(), system(), and strdup() may also throw. (strdup() is defined but not guaranteed to exist.)
  • setjmp() and catch(...) don't mix. At least one platform implemented longjmp() as the logical equivalent of throw jmp_buf, causing catch(...) to catch it.
  • Undefined behavior may throw. Some systems actually do implement *NULL as throw exception that can be caught by catch(...) even when compiling C code. If you execute undefined behavior anywhere, the entire program is undefined as soon as the code path is irrevocably committed to reaching undefined behavior, so this can cause C standard library functions to throw.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!