Clang 中的 C++ 支持

Clang 实现以下已发布和即将发布的 ISO C++ 标准

语言标准 标志 Clang 中可用?
C++2c -std=c++2c 部分
C++23 -std=c++23 部分
C++20 -std=c++20 部分
C++17 -std=c++17 Clang 5
C++14 -std=c++14 Clang 3.4
C++11 -std=c++11 Clang 3.3
C++98 / C++03 -std=c++98 是(除了导出)

Clang 社区不断努力通过提交和跟踪 C++缺陷报告 并在可用时实施解决方案,以在发行版之间提高 C++ 标准合规性。

还正在进行实验性工作来实施 C++ 技术规范,这将有助于推动 C++ 编程语言的未来。

LLVM 错误跟踪器 中使用“c++”标签以及“c++11”、"c++14"等模式特定标签来跟踪 Clang 语言一致性方面已知错误。

C++2c 实现状态

Clang 支持 C++23 之后,非正式称为 C++26 的 C++ 标准的一些功能。

可以使用 -std=c++2c 选项在 C++2c 模式下使用 Clang。

支持功能列表和最小 Clang 版本
语言功能 C++26 提案 Clang 中可用?
从词法分析中删除未定义的行为 P2621R2 (DR) Clang 3.3
使不可编码的字符串文字成为非法的 P1854R4 (DR) Clang 14
未评估的字符串 P2361R6 Clang 18
将 @、$ 和 ` 添加到基本字符集 P2558R2
void* P2738R1 Clang 17
关于标准属性的可忽略性 P2552R3 (DR)
花括号初始化的静态存储 P2752R3 (DR)
用户生成的static_assert消息 P2741R3 Clang 17
没有名称的占位符变量 P2169R4 Clang 18
模板参数初始化 P2308R1 (DR) Clang 18
包索引 P2662R3 Clang 19
删除枚举的已弃用算术转换 P2864R2 Clang 18
禁止将返回的 glvalue 绑定到临时变量 P2748R5 Clang 19
澄清聚合初始化中花括号省略的规则 P3106R1 (DR) Clang 17
结构化绑定的属性 P0609R3 Clang 19
模块声明不应该是宏 P3034R1 (DR)
平凡的无限循环不是未定义行为 P2809R3 (DR) Clang 19
未初始化读取的错误行为 P2795R5
= delete("应该有理由"); P2573R2 Clang 19
可变参数朋友 P2893R3 Clang 20
constexpr放置 new P2747R2 Clang 20
删除指向不完整类型的指针应该是非法的 P3144R2 Clang 19
涉及折叠表达式的约束的排序 P2963R3 Clang 19
结构化绑定声明作为条件 P0963R3

C++23 实现状态

Clang 支持 ISO C++ 2023 标准的一些功能。

可以使用 -std=c++23 选项在 C++23 模式下使用 Clang。

支持功能列表和最小 Clang 版本
语言功能 C++23 提案 Clang 中可用?
文字后缀uz, zforsize_t, ssize_t P0330R8 Clang 13
使()在所有情况下 lambda 中可选 P1102R2 Clang 13
更简单的隐式移动 P2266R3 Clang 13
if consteval P1938R3 Clang 14
允许重复属性 P2156R1 (DR) Clang 13
对 bool 的收缩上下文转换 P1401R5 Clang 14
在行拼接之前修剪空白 P2223R2
使声明顺序布局成为强制性 P1874R4
使用 UAX 31 的 C++ 标识符语法 P1949R7 (DR) Clang 14
混合字符串文字连接 P2201R1
推断 this P0847R7 Clang 18
P2797R0 Clang 19
更改 lambda 尾随返回类型的范围 P2036R3 (DR) Clang 17
P2579R0 (DR)
多维下标运算符 P2128R6 Clang 15
constexpr 函数中的非文字变量(以及标签和 goto) P2242R3 Clang 15
诊断文本的字符编码 P2246R1
字符集和编码 P2314R4
一致的字符文字编码 P2316R2
添加对预处理指令 elifdef 和 elifndef 的支持 P2334R1 Clang 13
扩展 init-statement 以允许别名声明 P2360R0 Clang 14
auto(x):语言中的衰减复制 P0849R8 Clang 15
Lambda 表达式的属性 P2173R1 Clang 13
constexprfor<cmath><cstdlib> P0533R9
类型特征以确定引用是否绑定到临时变量 P2255R2 Clang 19
您正在寻找的相等运算符 P2468R2 (DR) Clang 16
取消对易失性复合运算的弃用 P2327R1 (DR) Clang 15
#warning 的支持 P2437R1
删除不可编码的宽字符文字和多字符宽字符文字 P2362R3 Clang 14
复合语句末尾的标签 P2324R2 Clang 16
分隔的转义序列 P2290R3 Clang 15
命名的通用字符转义 P2071R2 Clang 15
放宽一些 constexpr 限制 P2448R2 Clang 19
在常量表达式中使用未知指针和引用 P2280R4 (DR)
static operator() P1169R4 Clang 16
扩展浮点类型和标准名称 P1467R9
从继承的构造函数中推断类模板参数 P2582R1
可移植假设 P1774R8 Clang 19
支持 UTF-8 作为可移植源文件编码 P2295R6 Clang 15
char8_t 兼容性和可移植性修复 P2513R3 (DR) Clang 16
放宽对 wchar_t 的要求以匹配现有做法 P2460R2 (DR)
显式生命周期管理 P2590R2
static operator[] P2589R1 Clang 16
允许 constexpr 函数中的静态 constexpr 变量 P2647R1 Clang 16
consteval 需要向上传播 P2564R3 (DR) Clang 17
基于范围的 for 循环中的生命周期扩展 P2718R0 Clang 20
引用 Unicode 标准 P2736R2

C++20 实现状态

Clang 支持 ISO C++ 2020 标准 的一些功能。

可以使用 -std=c++20 选项在 C++20 模式下使用 Clang(在 Clang 9 及更早版本中使用 -std=c++2a)。

支持功能列表和最小 Clang 版本
语言功能 C++20 提案 Clang 中可用?
位域的默认成员初始化器 P0683R1 Clang 6
const&限定的指向成员的指针 P0704R1 Clang 6
允许 lambda-capture[=, this] P0409R2 Clang 6
__VA_OPT__用于预处理器逗号省略 P0306R4 Clang 6
P1042R1 Clang 9
指定初始化器 P0329R4 Clang 10
template-parameter-list 用于通用 lambda P0428R2 Clang 9
概念 P0734R0 Clang 10
P0857R0 Clang 16
P1084R2 Clang 10
P1141R2
P0848R3 Clang 19
P1616R1 Clang 10
P1452R2
P1972R0 Clang 10
P1980R0
P2103R0
P2493R0 (DR)
P2092R0 Clang 16
P2113R0 Clang 16
带初始化器的基于范围的 for 语句 P0614R1 Clang 8
ADL 和不可见的函数模板 P0846R0 Clang 9
const与默认的复制构造函数不匹配 P0641R2 Clang 8
一致的比较(operator<=>) P0515R3 Clang 10
P0905R1
P1120R0
P1185R2
P1186R3
P1630R1
P1946R0
P1959R0
P2002R1 Clang 17
P2085R0 Clang 14
对特化的访问检查 P0692R1 Clang 14
默认可构造和可分配的无状态 lambda P0624R2 Clang 8
在未评估的上下文中使用 lambda P0315R4 Clang 17
[[no_unique_address]]属性 P0840R2 Clang 9
[[likely]][[unlikely]]属性 P0479R5 Clang 12
typename在更多上下文中可选 P0634R3 Clang 16
lambda init-capture 中的包展开 P0780R2 Clang 9
类类型作为非类型模板参数 P0732R2 Clang 12
标量类型的通用非类型模板参数 P1907R1
Clang 18(部分)引用类型模板参数引用与实例化相关的对象和子对象(即在模板内声明,但既不依赖于类型也不依赖于值)不受完全支持。
销毁 operator delete P0722R3 Clang 6
放宽constexpr限制 P1064R0 Clang 9
P1002R1 Clang 8
P1327R1 Clang 9
P1330R0
P1331R2 Clang 10
P1668R1
P0784R7
禁止具有用户声明构造函数的聚合 P1008R1 Clang 8
功能测试宏 P0941R2 (见下文)
explicit(bool) P0892R2 Clang 9
有符号整数是二进制补码 P1236R1 Clang 9
char8_t P0482R6 Clang 7 (11)
立即函数(consteval) P1073R3 Clang 17
P1937R2 Clang 14
std::is_constant_evaluated P0595R2 Clang 9
嵌套内联命名空间 P1094R2 Clang 8
结构化绑定扩展 P1091R3 Clang 16
P1381R1
更严格的 Unicode 要求 P1041R4
P1139R2
聚合的带括号初始化 P0960R3 Clang 16
P1975R0
模块 P1103R3 Clang 15
P1766R1 (DR) Clang 11
P1811R0
P1703R1 被 P1857 替代
P1874R1 Clang 15
P1979R0
P1779R3 Clang 15
P1857R3
P2115R0 部分
P1815R2 部分
P2615R1 (DR)
P2788R0 (DR)
协程 P0912R5
部分在所有目标上都得到完全支持,除了 Windows,Windows 仍然存在一些稳定性和 ABI 问题。
弃用a[b,c] P1161R3 Clang 9
弃用 volatile 的一些有问题的用法volatile P1152R4 Clang 10
[[nodiscard("有理由")]] P1301R4 Clang 9
using enum P1099R5 Clang 13
用于聚合的类模板参数推断 P1816R0 Clang 17
P2082R1
用于别名模板的类模板参数推断 P1814R0
Clang 19(部分)此功能已最初完成,但功能宏 __cpp_deduction_guides 尚未更新。
允许转换为未知边界数组 P0388R4 Clang 14
constinit P1143R2 Clang 10
伪析构函数结束对象生命周期 P0593R6 (DR) Clang 11
更多隐式移动 P1825R0 (DR) Clang 13

(11): 在 Clang 8 之前,此功能未启用-std=c++20,但可以使用以下方式启用-fchar8_t.

C++17 实现状态

Clang 5 及更高版本实现了 ISO C++ 2017 标准 的所有功能。

默认情况下,Clang 16 或更高版本根据 C++17 标准构建 C++ 代码。可以使用 -std=c++17 选项以 C++17 模式使用 Clang(在 Clang 4 及更早版本中使用 -std=c++1z)。

支持功能列表和最小 Clang 版本
语言功能 C++17 提案 Clang 中可用?
static_assert无消息 N3928 Clang 3.5
默认情况下禁用三元组扩展 N4086 Clang 3.5
typename在模板模板参数中 N4051 Clang 3.5
新的auto直接列表初始化规则N3922 Clang 3.8 (8)
折叠表达式 N4295 Clang 3.6
P0036R0 Clang 3.9
u8字符文字 N4267 Clang 3.6
嵌套命名空间定义 N4230 Clang 3.6
命名空间和枚举的属性 N4266 Clang 3.6
允许对所有非类型模板参数进行常量求值 N4268 Clang 3.6
删除已弃用的register存储类 P0001R1 Clang 3.8
删除已弃用的bool增量 P0002R1 Clang 3.8
使异常规范成为类型系统的一部分 P0012R1 Clang 4
__has_include在预处理器条件中 P0061R1
[[fallthrough]]属性 P0188R1 Clang 3.9
[[nodiscard]]属性 P0189R1 Clang 3.9
P1771R1 (DR) Clang 9
[[maybe_unused]]属性 P0212R1 Clang 3.9
具有基类的类的聚合初始化 P0017R1 Clang 3.9
constexprlambda 表达式 P0170R1 Clang 5
不同的beginend基于范围的类型for P0184R0 Clang 3.9
lambda 捕获*this P0018R3 Clang 3.9
直接列表初始化enums P0138R2 Clang 3.9
十六进制浮点文字 P0245R1
在不重复的情况下使用属性命名空间 P0028R4 Clang 3.9
为超对齐数据动态分配内存 P0035R4 Clang 4
类模板的模板参数推断 P0091R3 Clang 5
P0512R0
P0620R0 (DR) Clang 7
P0702R1 (DR) Clang 6
具有autotype P0127R2 Clang 4
保证复制省略 P0135R1 Clang 4
更严格的表达式求值顺序 P0145R3 Clang 4 (9)
P0400R0
忽略未知属性的要求 P0283R2
constexpr if 语句 P0292R2 Clang 3.9
内联变量 P0386R2 Clang 3.9
结构化绑定 P0217R3 Clang 4
P0961R1 (DR) Clang 8
P0969R0 (DR) Clang 8
将变量和条件分开ifswitch P0305R1 Clang 3.9
将模板模板参数匹配到兼容的参数 P0522R0 (DR) Clang 19 (10)
删除已弃用的动态异常规范 P0003R5 Clang 4
using 声明中的包扩展 P0195R2 Clang 4

(8): 这是一个向后不兼容的更改,它被应用于所有允许从auto(根据 C++ 委员会的要求)进行类型推断的语言版本。在 Clang 3.7 中,会对所有会改变含义的情况发出警告。
(9): 在 MS ABI 中,函数参数在被调用者中从左到右销毁。因此,在调用operator<<, operator>>, operator->*, operator&&, operator||operator,使用表达式语法的函数不再保证在该 ABI 中以相反的构造顺序销毁。在 Clang 12 之前,这在常量表达式求值期间不被完全支持。
(10): 虽然此功能最初是在 Clang 4 中实现的,但在 Clang 19 之前默认情况下并未启用,但可以使用-frelaxed-template-template-args启用。从 Clang 19 开始,该标志已弃用,并将从未来版本中删除。

C++14 实现状态

Clang 3.4 及更高版本实现了 ISO C++ 2014 标准 的所有功能。

可以使用 -std=c++14 选项以 C++14 模式使用 Clang(在 Clang 3.4 及更早版本中使用 -std=c++1y)。

支持功能列表和最小 Clang 版本
语言功能 C++14 提案 Clang 中可用?
对某些 C++ 上下文转换进行调整 N3323 Clang 3.4
二进制文字 N3472 Clang 2.9
decltype(auto) N3638 Clang 3.3
普通函数的返回类型推断 Clang 3.4
初始化的 lambda 捕获 N3648 Clang 3.4
泛型 lambda N3649 Clang 3.4
变量模板 N3651 Clang 3.4
放宽对 constexpr 函数的要求 N3652 Clang 3.4
成员初始化器和聚合 N3653 Clang 3.3
澄清内存分配 N3664 Clang 3.4
[[deprecated]]属性 N3760 Clang 3.4
单引号作为数字分隔符 N3781 Clang 3.4
C++ 调整大小的释放 N3778 Clang 3.4 (7)

(7): 用户必须提供调整大小的释放函数的定义,无论是显式提供还是使用提供这些函数的 C++ 标准库。libstdc++ 在版本 5.0 中添加了这些函数,libc++ 在版本 3.7 中添加了这些函数。用户也可以使用 -fno-sized-deallocation 选项禁用调整大小的释放。

C++11 实现状态

Clang 3.3 及更高版本实现了 ISO C++ 2011 标准 的所有功能。

可以使用 -std=c++11 选项以 C++11 模式使用 Clang。Clang 的 C++11 模式可以与 libc++ 或 gcc 的 libstdc++ 一起使用。

支持功能列表和最小 Clang 版本
语言功能 C++11 提案 Clang 中可用?
右值引用 N2118 Clang 2.9
P1825R0 (DR) Clang 13
    *this 的右值引用 N2439 Clang 2.9
通过右值初始化类对象 N1610 Clang 2.9
非静态数据成员初始化器 N2756 Clang 3.0
可变参数模板 N2242 Clang 2.9
    扩展可变参数模板模板参数 N2555 Clang 2.9
初始化列表 N2672 Clang 3.1
P1009R2 (DR) Clang 9
P1957R2 (DR) Clang 11
静态断言 N1720 Clang 2.9
auto 类型变量 N1984 Clang 2.9
    多声明器 auto N1737 Clang 2.9
    删除 auto 作为存储类说明符 N2546 Clang 2.9
    新的函数声明符语法 N2541 Clang 2.9
lambda 表达式 N2927 Clang 3.1
P0588R1 (DR)
表达式的声明类型 N2343 Clang 2.9
    不完整的返回类型 N3276 Clang 3.1
右尖括号 N1757 Clang 2.9
函数模板的默认模板参数 DR226 Clang 2.9
解决表达式的 SFINAE 问题 DR339 Clang 2.9
别名模板 N2258 Clang 3.0
外部模板 N1987 Clang 2.9
空指针常量 N2431 Clang 3.0
强类型枚举 N2347 Clang 2.9
枚举的向前声明 N2764
DR1206
Clang 3.1
标准化属性语法 N2761 Clang 3.3 (1)
泛化的常量表达式 N2235 Clang 3.1
P0859R0 (DR) Clang 8
对齐支持 N2341 Clang 3.3
有条件地支持的行为 N1627 Clang 2.9
将未定义的行为更改为可诊断的错误 N1727 Clang 2.9
委托构造函数 N1986 Clang 3.0
继承构造函数 N2540 Clang 3.3
P0136R1 (DR) Clang 3.9
显式转换运算符 N2437 Clang 3.0
新的字符类型 N2249 Clang 2.9
Unicode 字符串文字 N2442 Clang 3.0
原始字符串文字 N2442 Clang 3.0
文字中的通用字符名称 N2170 Clang 3.1
用户定义的文字 N2765 Clang 3.1
标准布局类型 N2342 Clang 3.0
默认函数 N2346 Clang 3.0
P1286R2 (DR) Clang 9
删除的函数 N2346 Clang 2.9
扩展的友元声明 N1791 Clang 2.9
扩展 sizeof N2253
DR850
Clang 3.1
内联命名空间 N2535 Clang 2.9
无限制联合 N2544 Clang 3.1
局部和未命名的类型作为模板参数 N2657 Clang 2.9
基于范围的 for N2930 Clang 3.0
P0962R1 (DR) Clang 8
显式虚拟重写 N2928
N3206
N3272
Clang 3.0
对垃圾回收和基于可达性的泄漏检测的最小支持 N2670 N/A (2)
允许移动构造函数抛出 [noexcept] N3050 Clang 3.0
定义移动特殊成员函数 N3053 Clang 3.0
并发性
序列点 N2239 Clang 3.3
原子操作 N2427 Clang 3.1
强比较和交换 N2748 Clang 3.1 (3)
双向栅栏 N2752 Clang 3.1
内存模型 N2429 Clang 3.2
数据依赖排序:原子和内存模型 N2664 Clang 3.2 (4)
传播异常 N2179 Clang 2.9
允许在信号处理程序中使用原子 N2547 Clang 3.1
线程局部存储 N2659 Clang 3.3 (5)
并发性的动态初始化和销毁 N2660 Clang 2.9
C99 特性在 C++11 中
__func__ 预定义标识符 N2340 Clang 2.9
C99 预处理器 N1653 Clang 2.9
long long N1811 Clang 2.9
扩展的整型 N1988 N/A (6)

(1): [[carries_dependency]] 属性没有效果。
(2): 对于像 Clang 这样的不提供垃圾回收的实现,不需要进行任何编译器更改。
(3): 所有比较和交换操作都作为强比较和交换发出。
(4): memory_order_consume 被降低到 memory_order_acquire
(5): thread_local 支持需要一个提供 __cxa_thread_atexit 的 C++ 运行时库,例如 libc++abi 3.6 或更高版本,或 libsupc++ 4.8 或更高版本。
(6): 对于像 Clang 这样的不提供任何扩展整型类型的实现,不需要进行任何编译器更改。__int128 不被视为扩展整型类型,因为更改 intmax_t 将是不兼容 ABI 的更改。

C++98 实现状态

Clang 实现了 ISO C++ 1998 标准(包括 ISO C++ 2003 标准中解决的缺陷)中的所有内容,除了导出(它在 C++11 中被删除了)。

缺陷报告

Clang 通常的目标是追溯地实现针对缺陷报告(针对先前标准的错误修复)的解决方案,在修复有意义的所有先前标准版本中。上述表格中标记了 (DR) 的标准发布后对语言特性的重大缺陷报告更改。

Clang 还拥有一个用于符合 C++ 核心问题列表 上问题解决方案的测试套件,其中大多数被视为缺陷报告。基于该测试套件的 C++ 核心问题的实现状态 在单独的页面上进行跟踪。

技术规范和常设文件

ISO C++ 还发布了一些文档,描述了标准 C++ 不包含的附加语言和库功能。

支持功能列表和最小 Clang 版本
文档 最新草案 编译器标志 Clang 中可用?
SD-6:SG10 特性测试建议 SD-6 N/A Clang 3.4 (N3745)
Clang 3.6 (N4200)
Clang 4 (P0096R3)
Clang 5 (P0096R4)
Clang 7 (P0096R5)
Clang 9 (P1353R0)
Clang 10 (P1902R1)
[TS] 概念 P0121R0 P0734R0 替代
[TS] 协程 N4663 -fcoroutines-ts
-stdlib=libc++
Clang 5
-std=c++20
-stdlib=libc++
P0912R5 替代
[TS] 库基础,版本 1(调用类型特征) N4480 N/A
[TS] 库基础,版本 2(source_location) N4617 N/A Clang 9 (文档)
[TS] 模块 N4720 -fmodules-ts 已被 P1103R3 取代
[DRAFT TS] 反射 N4818
[TS] 事务性内存 N4514