且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么在STL中允许未定义的行为?

更新时间:2023-11-05 23:24:58

当允许未定义的行为时,为了效率的原因通常 >

如果标准指定了当您访问数组超出边界时必须发生的事情,它将强制实现检查索引是否在边界。这同样适用于一个向量,它只是一个动态数组的包装器。



在其他情况下,允许未定义行为以允许***的实现。但是,这也是真正的效率(因为一些可能的实现策略在一些机器上比在其他机器上更有效,而C ++如果他们愿意,可以选择最有效的策略)。


By default, the "underlying container" of an std::stack is an std::deque. Therefore anything that is undefined behavior for a std::deque is undefined behavior for a std::stack. cppreference and other sites use the terminology "effectively" when describing the behavior of member functions. I take this to mean that it is for all intents and purposes. So therefore, calling top() and pop() is equivalent to calling back() and pop_back(), and calling these on an empty container is undefined behavior.

From my understanding, the reason why it's undefined behavior is to preserve the no-throw guarantee. My reasoning is that operator[] for std::vector has a no-throw guarantee and is undefined behavior if container size is greater than N, but at() has a strong guarantee, and throws std::out_of_range if n is out of bounds.

So my question is, what is the rationale behind some things having possibly undefined behavior and having a no throw guarantee versus having a strong guarantee but throwing an exception instead?

When undefined behaviour is allowed, it's usually for reasons of efficiency.

If the standard specified what has to happen when you access an array out of bounds, it would force the implementation to check whether the index is in bounds. Same goes for a vector, which is just a wrapper for a dynamic array.

In other cases the behaviour is allowed to be undefined in order to allow freedom in the implementation. But that, too, is really about efficiency (as some possible implementation strategies could be more efficient on some machines than on others, and C++ leaves it up to the implementer to pick the most efficient strategy, if they so desire.)