Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
292 views
in Technique[技术] by (71.8m points)

c++ - Why is C++0x's `noexcept` checked dynamically?

I am curious about the rationale behind noexcept in the C++0x FCD. throw(X) was deprecated, but noexcept seems to do the same thing. Is there a reason that noexcept isn't checked at compile time? It seems that it would be better if these functions were checked statically that they only called throwing functions within a try block.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Basically, it's a linker problem, the standards committee was reluctant to break the ABI. (If it were up to me, I would do so, all it really requires is library recompilation, we have this situation already with thread enablement, and it's manageable.)

Consider how it would work out. Suppose the requirements were

  1. every destructor is implicitly noexcept(true)
    • Arguably, this should be a strict requirement. Throwing destructors are always a bug.
  2. every extern "C" is implicitly noexcept(true)
    • Same argument again: exceptions in C-land are always a bug.
  3. every other function is implicitly noexcept(false) unless otherwise specified
  4. a noexcept(true) function must wrap all its noexcept(false) calls in try{}catch(...){}
    • By analogy, a const method cannot call a non-const method.
  5. This attribute must manifest as a distinct type in overload resolution, function pointer compatibility, etc.

Sounds reasonable, right?

To implement this, the linker needs to distinguish between noexcept(true) and noexcept(false) versions of functions, much as you can overload const and const versions of member functions.

So what does this mean for name-namgling? To be backwards-compatible with existing object code we would require that all existing names are interpreted as noexcept(false) with extra mangling for the noexcept(true) versions.

This would imply we cannot link against existing destructors unless the header is modified to tag them as noexcept(false)

  • this would break backwards compatibility,
  • this arguably ought to be impossible, see point 1.

I spoke to a standards committe member in person about this and he says that this was a rushed decision, motivated mainly by a constraint on move operations in containers (you might otherwise end up with missing items after a throw, which violates the basic guarantee). Mind you, this is a man whose stated design philosophy is that fault intolerant code is good. Draw your own conclusions.

Like I said, I would have broken the ABI in preference to breaking the language. noexcept is only a marginal improvement on the old way. Static checking is always better.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...