为什么STL实现不使用断言来检测未定义的行为?

mwn*_*wnx 1 c++ assert stl

这是我认为可能有用但我没有看到在gcc的标准库中实现的东西.

基本上,在我看来,STL实现可以添加断言来检测(在运行时)简单的错误,如越界访问.我猜这些访问在标准中无论如何都是未定义的行为,所以肯定会打印错误消息并且-optionally-aborting将符合标准.

这些断言当然可以在编译时通过旧的NDEBUG标志或其他标志来关闭.

作为一个小例子,我希望此代码中止:

#include <vector>

int main()
{
    return std::vector<int>{1,2}[2];
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我充分意识到像valgrind这样的工具的存在,但这可能是一个奖励.此外,像valgrind这样的内存检查工具不能保证在向量缩小后检测某些错误,例如访问越界元素,因为实现可能不会立即重新分配底层内存.

Jon*_*ely 7

这是我认为可能有用但我没有看到在gcc的标准库中实现的东西.

你错了,尝试定义_GLIBCXX_DEBUG,这会使你的例子中止:

/home/jwakely/gcc/5/include/c++/5.0.0/debug/vector:402:error: attempt to 
    subscript container with out-of-bounds index 2, but container only 
    holds 2 elements.

Objects involved in the operation:
sequence "this" @ 0x0x7fffb8b221a0 {
  type = NSt7__debug6vectorIiSaIiEEE;
}
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

这些断言当然可以在编译时通过旧的NDEBUG标志或其他标志来关闭.

之所以这样使用一个独立的机制,而不是assert()NDEBUG是因为检查增加了开销,所以明确要求时,才启用.这意味着用户可以继续使用assert()自己的检查,而无需打开标准库检查的开销.由于用于跟踪迭代器有效性的其他数据成员,还有libstdc ++的调试模式需要注意的二进制兼容性问题.有关详细信息,请参阅https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html.

Libc ++也有类似的检查,使用不同的宏,VC++在调试版本中自动启用类似的检查.