No, I don't think so, but it's undefined behavior to let a C++
exception propagate through C code.
What else could the C++ standard say about it? The C++ standard
cannot specify behavior in another language, so anything
happening in that language is undefined behavior.
Like all undefined behavior, it can be defined by the
implementation, and all of the implementations I know do define
it so that the exception will propagate through the C code. In
practice, I think it's something you can more or less count on,
*IF* the C and the C++ compiler come from the same source.
And extern "C" isn't very meaningful except to have that
function called by C code.
Hence in your real set-up, as opposed to what you've shown,
you probably have undefined behavior, in practice that cleanup
isn't performed during stack unwinding through the C code.
That's a different issue. C doesn't have any defined "cleanup"
to be performed, but you're almost certainly right that the C
programmer didn't design his code to be exception safe. So even
if the behavior is defined, it's likely in most cases to be
defined as something which won't work.
There is one major exception, I think: a lot of API's are
defined in terms of C (and require `extern "C"' on callback
functions passed into them), but are designed to be used from
both C and C++. In such cases, the library programmer does know
that C++ (and exceptions) is a possibility, and may have taken
it into account; if the library documents that exceptions will
propagate in such cases, you can use them. (Any library
*should* document such things. I have a sneaking suspicion,
however, than many don't.)
Note too that often, when passing a pointer to a function to
such an API, the function will be called asynchronously, much
later. For obvious reasons, exceptions can't be used there.