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 |
不同的begin和end基于范围的类型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 | |
将变量和条件分开if和switch | 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 | 否 |