13. 与标准的差异(ISO/IEC 14882:2014 / C++14)
本章是本文档的符合性声明部分。判定基准为 ISO/IEC 14882:2014(C++14),判定对象为本文档所描述的交付库。
节 内容 13.1 支持标准、判定基准与可声明符合度 13.2 相对标准的缺失(硬偏差 D1 / D2 / D8 / D11 / D12) 13.3 标准之外的内容(本手册不描述) 13.4 交付配置下不可用的标准组件 13.5 其他偏差、环境限制与使用须知 13.6 交付配置核对 13.7 使用限制汇总
13.1 支持标准、判定基准与可声明符合度
| 项 | 内容 |
|---|---|
| 支持标准 | ISO/IEC 14882:2014 C++14 |
| 语言模式 | -std=c++14 |
| 可声明符合 | C++14 核心库语义符合——容器、迭代器、算法、数值、工具、字符串(第 17–26 章主体),以及 C++14 主要增补特性(make_unique/exchange/integer_sequence/_t 别名族/透明比较器/时长字面量等) |
| 不可声明符合 | §15 [except] 异常处理整章;§29 [atomics] 运行期;§27 [input.output] 整章;§22 [localization] 整章;§19.5 [syserr] 整节(见 D11) |
13.2 相对标准的缺失(硬偏差)
| 编号 | 缺失项 | 影响范围(C++14 条款) | 状态 |
|---|---|---|---|
| D1 | 异常处理整章不可用(-fno-exceptions) | §15 [except] 整章(含 §15.3 [except.handle])、§18.8 [support.exception.term] | 默认配置三层关闭异常,用户不可触发 |
| D2 | atomics 运行期无实现(__sync_*/__atomic_* 无符号) | §29 [atomics] 可编译不可运行(§29.5/§29.6);无锁豁免不适用 | 限制(工具链) |
| D8 | iostreams 结构性不可编译(宽字符/本地化守卫链缺失) | §27 [input.output] 整章、§22 [localization] | 限制(交付配置) |
| D11 | <system_error> 整节不可链接(依赖 __sync_val_compare_and_swap_1) | §19.5 [syserr] 整节;§21.5 [string.conversions] 中依赖 system_error 的部分 | 限制(工具链,同 D2) |
| D12 | <cuchar> 头缺失 | §17.6.1.2 [headers] Table 15 | 偏差(头文件) |
编号说明:D1–D12 为限制/偏差编号,其中硬偏差集中在 13.2(D1 / D2 / D8 / D11 / D12),环境与使用须知类在 13.5(D3–D7 / D9 / D10)。
同一守卫链导致同样不可用的 C++14 标准头:<cwchar>、<cwctype>、<wchar.h>、<codecvt>、<regex>、<locale> / <clocale>。
13.3 标准之外的内容(本手册不描述)
本库源码树中包含若干不属于 C++14 的实体(C++17 / C++20 / C++23 引入,以及个别 DIS 之后才合入的内容)。其中大部分被 _LIBCPP_STD_VER 阈值守卫排除,在 -std=c++14 下不可用;个别实体未加守卫而在本库中可用。
**这些内容不属于本手册声明的 C++14 范围,本手册不作描述,也不构成对其可用性、行为或长期兼容性的承诺。**如需使用,须改用相应的 -std=c++NN 模式并重新评估认证范围;功能安全项目中若使用,须单独评估并纳入相应的验证范围。
13.4 交付配置下不可用的标准组件
以下均为 C++14 标准组件,仅因交付配置裁剪而不可用(不是标准符合性缺陷)。其中 第 2 章(atomics)与第 5 章(IO)已整章移出正文(见各章开头的边界说明);第 4 章(诊断与异常)的 4.2 系统错误一节因属 D11 限制而非配置裁剪,已一并移出。
| 组件 | 配置依据(宏) | 影响 |
|---|---|---|
异常语义(throw/try/catch、异常类的抛出路径) | -fno-exceptions → _LIBCPP_NO_EXCEPTIONS | 第 4 章 4 / 4.1 的异常类类定义可用(可构造、what() 正常),但抛 / 接路径不可用;与 D1 叠加 |
<thread> / <mutex> / <condition_variable> / <future> / <shared_mutex> | _LIBCPP_HAS_NO_THREADS | §30 [thread] 整章不可用 |
本地化 [locale] / facet / <codecvt> / <regex> | _LIBCPP_HAS_NO_LOCALIZATION;另受 D8 影响 | §22 [localization] 整章、§28 [re] 不可用 |
宽字符(<cwchar> / <cwctype> / <wchar.h> / 宽 traits 特化) | _LIBCPP_HAS_NO_WIDE_CHARACTERS | D8 的直接触发点 |
| iostreams(第 5 章全部) | 见 D8 | §27 [input.output] 不可用 |
| atomics 运行期(第 2 章全部) | 见 D2 | 编译期可用,运行期链接失败 |
| 系统错误(4.2 全部) | 见 D11 | 依赖 __sync_* 原子符号,链接期失败(非配置裁剪) |
13.5 其他偏差、环境限制与使用须知
| 编号 | 项 | 说明 | 定性 / 条款 |
|---|---|---|---|
| D3 | OOM 失败路径不健壮 | 堆满时 malloc/operator new 返回 NULL,容器不判空 → 野指针/非法取指(SIGILL)。堆上限约 64K–256K | 限制;§18.6.1.1、§3.7.4.1 |
| D4 | 部分 O(n²) 用例在仿真器下挂起(> 60 min) | 相关用例在真机板测中全部通过 → 仿真器吞吐限制,非语义缺陷 | 环境 |
| D5 | clock() 恒 0 → 时钟断言失败 | 仿真器与真机两环境均"时间源未接线"(真机非零但冻结于默认纪元)→ 与库实现无关 | 环境;§20.12.2 [time.clock] |
| D6 | stod("1.e60") / stold 差 1 ULP | 十进制→二进制转换在极大指数边界未落到最近可表示值。std::stod 委托底层 C 库 strtod 实现 | 结果偏差;§21.5 [string.conversions] |
| D7 | allocator-extended function 构造 | 与本交付配置编译不兼容;不影响同族语义 | 配置不兼容 |
| D9 | sized deallocation 默认关闭 | 加 -fsized-deallocation 后 __cpp_sized_deallocation == 201309L;默认 -std=c++14 不启用 | 偏差(工具链默认值);§18.6.1.1/§18.6.1.2、§12.5 |
| D10 | __config_site 不被驱动自动加载 | 直接指向源码 include/ 编译时须用 -D 指定配置宏;交付头目录自带该文件,不影响使用 | 限制(工程可用性);§17.6.1.2 |
| — | 文档化不支持 | concepts、experimental、localization、pstl、re、thread(与库门控一致) | 已声明 |
13.6 C++14 交付配置核对
13.6.1 C++14 核心组件与 C++14 增补特性(26 + 15 项)
| # | 检查项 | 结果 | # | 检查项 | 结果 |
|---|---|---|---|---|---|
| A1 | 序列容器 vector | √ | A18 | valarray | √ |
| A2 | list / deque / forward_list | √ | A19 | scoped_allocator / initializer_list / typeindex | √ |
| A3 | array | √ | A20 | strstream | × |
| A4 | 关联容器 map / set | √ | A21 | bitset | √ |
| A5 | 无序关联容器 unordered_* | √ | A22 | random | √ |
| A6 | 适配器 stack / queue / priority_queue | √ | A23 | cmath | √ |
| A7 | 迭代器与 make_reverse_iterator | √ | A24 | raw_storage_iterator / is_literal_type / result_of | √ |
| A8 | <algorithm> 基本算法 | √ | A25 | <stdexcept> / <system_error> 诊断类 | √ |
| A9 | basic_string | √ | A26 | <atomic> 编译期 | √ |
| A10 | pair / tuple | √ | B1 | std::make_unique | √ |
| A11 | function / bind / reference_wrapper | √ | B2 | std::exchange | √ |
| A12 | unique_ptr / shared_ptr / weak_ptr | △ | B3 | integer_sequence / index_sequence | √ |
| A13 | type_traits 基本特征 | √ | B4 | _t 别名族 | √ |
| A14 | numeric_limits | √ | B5 | 双区间 equal / mismatch / is_permutation | √ |
| A15 | complex | √ | B6 | hash<enum> | √ |
| A16 | ratio | √ | B7 | less<> 透明比较器 | √ |
| A17 | chrono duration / time_point | √ | B8 | 1s / 500ms 时长字面量 | √ |
| B9 | operator""s | √ | |||
| B10 | array / complex 的 constexpr | √ | |||
| B11 | 泛型 lambda(auto 参数) | √ | |||
| B12 | lambda 返回类型推导 | √ | |||
| B13 | 变量模板 | √ | |||
| B14 | [[deprecated]] | △(触发 -Wdeprecated-declarations,属预期) | |||
| B15 | std::get<T>(tuple) | √ |
图例:√ 可用 | △ 需注意 | × 不可用。其中 B14 的 △ = 触发
-Wdeprecated-declarations(属预期);A12 的 △ =shared_ptr/weak_ptr在-frtti下链接失败(见 13.7.1 L1)。结论:C++11/14 核心组件与 C++14 相对 C++11 的全部主要增补特性均可用(唯一的例外见上表 A20
<strstream>);但 A12 需修正:unique_ptr可用,shared_ptr/weak_ptr默认不可链接。
13.6.2 交付配置下不可用(与 13.4 一致)
| # | 检查项 | 结果 | 诊断信息 |
|---|---|---|---|
| C1 | <thread> | × | <thread> is not supported on this single threaded system |
| C2 | std::mutex(<mutex>) | × | no type named 'mutex' in namespace 'std' |
| C3 | <future>(std::future) | × | <thread> is not supported … |
| C4 | std::condition_variable | × | no type named 'condition_variable' … |
| C5 | <shared_mutex>(std::shared_mutex) | × | <shared_mutex> is not supported on this single threaded system |
| C6 | <iostream> | × | <wctype.h> is not supported …(D8 的宽字符链) |
| C7 | <sstream> | × | 同上 |
| C8 | <fstream> | × | 同上 |
| C9 | <ios> | × | 同上 |
| C10 | <locale> | × | 同上 |
| C11 | <regex> | × | 同上 |
| C12 | <codecvt> | × | 同上 |
| C13 | <cwchar> | × | <wctype.h> is not supported … |
| C14 | <cwctype> | × | 同上 |
| C15 | <wchar.h> | × | The <wchar.h> header is not supported since libc++ has been configured with LIBCXX_ENABLE_WIDE_CHARACTERS disabled |
| C16 | try / catch(-fno-exceptions) | × | cannot use 'try' with exceptions disabled |
| C17 | throw(-fno-exceptions) | × | cannot use 'throw' with exceptions disabled |
| C18 | <cuchar> | × | 'cuchar' file not found(13.2 D12) |
13.6.3 非 C++14 实体(应被 -std=c++14 排除)
(1)已按标准守卫正确排除 —— 19 项
| # | 检查项 | 实际标准 | 结果 |
|---|---|---|---|
| X1 | std::optional | C++17 | × |
| X2 | std::variant | C++17 | × |
| X3 | std::any | C++17 | × |
| X4 | std::clamp | C++17 | × |
| X5 | std::sample | C++17 | × |
| X6 | std::gcd / lcm | C++17 | × |
| X7 | std::reduce | C++17 | × |
| X8 | std::bool_constant | C++17 | × |
| X9 | std::void_t | C++17 | × |
| X10 | std::invoke_result | C++17 | × |
| X11 | conjunction / disjunction / negation | C++17 | × |
| X12 | 非成员 std::size / empty / data | C++17 | × |
| X13 | std::apply | C++17 | × |
| X14 | std::invoke | C++17 | × |
| X15 | std::construct_at / destroy_at | C++20 / C++17 | × |
| X16 | std::popcount 等 <bit> 族 | C++20 | × |
| X17 | std::lerp | C++20 | × |
| X18 | basic_string::starts_with | C++20 | × |
| X19 | std::span | C++20 | × |
(2)未加守卫而泄漏可用 —— 3 项(属标准外内容,见 13.3)
| 检查项 | 实际标准 | 结果 |
|---|---|---|
std::string_view | C++17 | √ 可用 |
<version> | C++20 | √ 可用 |
std::uncaught_exceptions | C++17 | √ 可用 |
13.6.4 其他核对结论与修正
| # | 项 | 结论 |
|---|---|---|
| E1 | sized deallocation 默认关闭(D9) | 默认 -std=c++14 下 __cpp_sized_deallocation 未定义 |
| E2 | <clocale> | √ 可用:std::localeconv() / std::setlocale() 经 C 库 <locale.h> 正常工作 |
| E3 | <cassert> / <cctype> | √ 可用 |
| E4 | <iosfwd> | √ 可用(纯前向声明) |
| E5 | __cplusplus | 201402L(C++14) |
| E6 | __config_site 的交付可用性(D10 澄清) | √ 交付头目录自带 __config_site,无需命令行 -D;D10 的"须靠 -D"仅适用于直接指向源码 include/ 的场景 |
13.6.5 正文条目级可见性核对
| 核对方式 | 覆盖 | 结果 |
|---|---|---|
| 章节覆盖 | 第 1/3/4/6/7/8/9/10/11/12 章各取一例,实际调用该章主要 API | 10/10 章编译通过 |
| 条目级可见性(预处理集合比对) | 正文 392 条条目的主标识符 | 392 条全部可见(余 2 条为提取误报:参数名 ptr、模板参数 R) |
本版据条目级核对修正 4 处:① 第 8 章头清单误列 C++20 的
<bit>/<numbers>;② 7.3true_type/false_type误用 C++17 的bool_constant<…>定义(C++14 实为integral_constant<bool, …>);③ 7.3 条目中混入 C++17 的is_aggregate;④ 9.1 条目中含 C++17 的operator basic_string_view。均已更正/移出。
13.7 使用限制汇总
本节把已知的全部限制与平台约束汇总为面向使用方的限制清单,可直接被认证材料与编码规范引用。 风险等级:高 —— 静默失效(程序不报错但结果不符预期)|中 —— 结果偏差(可观测但需留意)|低 —— 能力边界(如实不提供,调用即失败)。
13.7.1 库功能限制
| # | 限制 | 现象 | 影响 | 规避措施 | 等级 |
|---|---|---|---|---|---|
| L1 | shared_ptr/weak_ptr/make_shared 不可用(链接期) | 链接失败:缺 typeinfo 符号(交付库只有 vtable) | 编译通过、链接失败;-frtti 默认开启 | 改用 unique_ptr | 低 |
| L2 | <wctype.h> / <wchar.h> 为硬错误 | 编译失败:The <wctype.h> header is not supported ... | 任何包含这两个头的翻译单元都无法编译 | 不包含宽字符头(见 13.4 C13–C15、C18) | 低 |
| L3 | 异常关闭 | 编译失败:cannot use 'throw' / 'try' with exceptions disabled | 见 13.4(C16 / C17) | 不使用 throw / try | 低 |
| L4 | 线程库不可用 | 编译失败:<thread> is not supported on this single threaded system 等 | 见 13.4(C1–C5) | 不使用 <thread> / <mutex> / <future> | 低 |
| L5 | 原子操作不可链接 | 链接失败:undefined symbol: __atomic_* / __sync_* | 见 13.2 D2 | 不使用 <atomic> | 低 |
| L6 | std::chrono::steady_clock 不可用 | 编译失败:no member named 'steady_clock' in namespace std::chrono | 计时相关代码无法移植 | 改用 system_clock 或平台计数器 | 中 |
| L7 | std::wstring / to_wstring 不可用 | 编译失败:no type named 'wstring' in namespace std、no member named 'to_wstring' | 宽字符串不可用 | 使用 std::string | 低 |
| L8 | rename() 缺失 | 链接失败:undefined symbol: rename | 与 C 侧一致(C 手册 10.2 G3) | 不使用 rename | 低 |
| L9 | <system_error> 整节不可链接 | std::error_code ec; 即链接失败(见 13.2 D11) | error_code/error_condition/system_error 全部不可用 | 改用返回值/枚举 | 低 |
编译失败的主要来源:宽字符头(L2)、异常关闭(L3)、线程库(L4)、原子操作(L5)四类,均源于交付配置裁剪,与 13.4「交付配置下不可用的标准组件」一致 —— 属已知边界。 L1 / L9 属链接期限制(编译通过、链接失败),不归入"配置裁剪";两者分别对应 13.7.1 与 13.2 D11。
13.7.2 前端(编译器)诊断限制 —— 126 条「应拒未拒」
在 -pedantic-errors 下编译,以下构造本应产生诊断而编译器未拒绝(诊断信息为 Compilation incorrectly passed),共 126 条。覆盖范围包括:预处理指令约束;声明与声明符(存储类、typedef、位域、数组大小、聚合初始化);表达式与语句(:? 缺操作数、alignof、逗号运算符);类成员与转换;异常处理;C++11 库条款与工具组件(容器、迭代器、字符串、数值、重载、词法、system_error);以及 C++14 新增特性(变量模板、显式实例化、泛型 lambda、放宽的 constexpr、sized deallocation、[[deprecated]])。
影响与规避:不得依赖编译器在编译期拦住上述构造;须由编码规范 / 静态检查兜底。
13.7.3 使用限制汇总
| 类别 | 条目 | 等级分布 |
|---|---|---|
| 库功能限制 | L1–L9 | 低 8 条(能力边界:如实不提供);中 1 条(L6 steady_clock) |
| 前端诊断限制 | 126 条「应拒未拒」 | 全部为诊断完备性缺口,不依赖即可 |