返回

文章详情

C++26: 标准库硬化实验

Hacker News2026年8月31日 14:52

“硬化”在2026年的C++世界中似乎是一个非常流行的术语。在本文中,我们将探索这个词的含义,并看到一些核心示例。一个硬化的库能使C++完全安全吗?我们来看看。核心思想当你学习std::vector时,可能会记得你可以使用至少两个表达式来访问第i个位置的元素:std::vector<int> v { 1, 2, 3, 4 }; v[i] = 10; // 对于某个i v.at(j) = 11; // 对于某个j 这两者之间的主要区别在于[]是未经检查的(如果你尝试访问一个不存在的元素,可能会生成未定义行为),而.at()可能会抛出std::out_of_range(所以这是一个良好定义的行为)。 C++26的变化在C++26中,标准引入了硬化实现的概念。标准库实现是否硬化,以及如何启用该模式,均由实现定义。对于std::vector<T, Allocator>::operator[](size_type pos) : C++标准条件在C++26之前如果pos < size()为假,则行为未定义。自C++26以来如果pos < size()为假:如果实现是硬化的,则发生合同违约;如果实现不是硬化的,则行为未定义。换句话说,如果你切换此“硬化”模式,你将得到一些良好指定的错误/违约,而不是仅仅是不确定的行为。让我们理清措辞和常见问题:对于.at()你可能会得到一个异常……那么我们为什么需要一个新的替代方案?这个问题是合理的。简而言之,at()和[]有不同的接口和性能/错误处理方法。更重要的是,你不能轻易地关闭异常(你可以这样做,但std::terminate将被调用,但这并不灵活)。因此,硬化并不会将operator[]更改为at()——它检测编程错误并终止,而不是允许内存不安全的未定义行为。“发生合同违约”——这是这里的关键。 “硬化”特性以合同的形式表示,这些合同也被纳入了C++26。C++26使用新的合同模型规定了硬化前置条件:在硬化实现中违反任何一条都会导致合同违约,以终止语义来评估。然而,库实现不一定使用实际的前置、后置或contract_assert语言语法来实现这些检查。那么什么是合同违约?普通C++26合同可能使用ignore、observe、enforce或quick-enforce语义。硬化标准库前置条件更具限制性:在硬化实现中,它们必须使用终止语义,因此在检查失败后无法继续执行。如何在这些模式之间切换取决于实现。这里可以阅读更多信息:合同断言(自C++26)- cppreference.com 它在运行时有效吗?是的,实际上它可以在常量表达式中运行,但更重要的是,它在运行时运行。这与GLIBCXX_ASSERTIONS、_ITERATOR_DEBUG_LEVEL等有什么关系?C++26试图将那些供应商特定的检查器引入并创建一套共同的、良好定义的规则。主要问题:如何启用这个功能?GCC / libstdc++: _GLIBCXX_ASSERTIONS启用轻量级标准库前置条件检查。GCC的更广泛的-fhardened选项自动与其他安全选项一起启用。Clang / libc++: 使用_LIBCPP_HARDENING_MODE,具有NONE、FAST、EXTENSIVE和DEBUG模式。MSVC STL: _MSVC_STL_HARDENING=1全局启用硬化。个体类型可以通过像_MSVC_STL_HARDENING_VECTOR和_MSVC_STL_HARDENING_OPTIONAL这样的宏进行控制。注意:在撰写时(2026年8月),编译器和库供应商仍在完成C++26特性。下面的选项是当前的供应商硬化机制,并不一定代表P3471/P3697/P3878核心文档和提案的完整实现。我们有以下文件使整项功能,在C++26下:P3471 - 主要标准库硬化 P3697 - C++26标准库硬化的小补充- basic_stacktrace, shared_ptr<T[N]>, view_interface (front, back), counted_iterator, common_iterator P3878 - 标准库硬化应使用终止语义。确保硬化前置条件违反不能简单地被观察到,然后继续到硬化意图防止的UB。硬化模式 -- libc++文档在标准中指定硬化,该提案引入了硬化前置条件的概念。硬化前置条件是在硬化实现中导致合同违约的前置条件。向库添加硬化主要由将现有的一些前置条件转换为规范中的硬化前置条件组成。哪些条件是硬化实现的候选者?违反前置条件导致内存安全问题(越界访问或访问未初始化内存);调用站点拥有所有必要的上下文。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡