在没有 -DNDEBUG 和 -O3 的情况下进行编译时,标准库实现不使用断言有什么原因吗?

Vit*_*meo 3 c++ assert std libstdc++

我无数次编写了在访问其内存或外部内存后生成分段错误的代码:std::vectorstd::string

std::string test{"hello!"};
std::cout << test[12] << std::endl;
Run Code Online (Sandbox Code Playgroud)

这是一个可以在非优化/调试构建中在运行时捕获的错误,只需简单断言的少量额外成本。(但由于我们正在构建没有-DNDEBUG和没有-O3我们不期望获得最大性能。)

有什么理由std::string::operator[]不这样实施吗?

标准是否禁止在库代码中使用断言?

char std::string::operator[](std::size_t i)
{
    // `assert_with_message` only exists in debug mode

    #ifndef NDEBUG
        assert_with_message(i < this->size(),
            "Tried to access character " + std::to_string(i)
            + " from string '" + *this + "' of size " 
            + std::to_string(this->size()));
    #endif

    return data[i];
}
Run Code Online (Sandbox Code Playgroud)

-DNDEBUG在没有编译程序的情况下编译程序并在运行时看到类似此消息的内容将非常有帮助:

断言已触发:尝试从字符串“hello!”访问字符 12 尺寸为 6。

按 (0) 继续。

按 (1) 中止。

请注意,术语“断言”指的是开发/调试构建检查,应从发布/优化构建中完全删除/优化该检查。

Mar*_*sse 5

标准库的几个实现确实在调试模式下提供了此类检查,但调试模式不受 NDEBUG 控制。对于 libstdc++,您需要-D_GLIBCXX_DEBUG(请参阅文档)。