Clang 中的 C 支持

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

语言标准 标志 Clang 中可用?
C2y -std=c2y 部分
C23 -std=c23 部分
C17 -std=c17 部分
C11 -std=c11 部分
C99 -std=c99 Clang 17
C89 -std=c89

目前正在调查 C11 和 C23 的实现状态。Clang 中目前状态未知的任何提案将在 洋红色 中标记。

Clang 社区不断努力通过提交和跟踪 C 缺陷报告 并在它们可用时实施解决方案来改进版本之间的 C 标准合规性。

LLVM 错误跟踪器 使用“c”、“c99”、“c11”、“c17”、“c23”和“c2y”标签来跟踪 Clang 语言一致性中的已知错误。

C2y 实现状态

Clang 支持 C23 之后,非正式地称为 C2y 的 C 标准的一些功能。

您可以使用 -std=c2y 选项(在 Clang 19 及更高版本中可用)在 C2y 模式下使用 Clang。

具有支持的特性列表和最低 Clang 版本
语言特性 C2y 提案 Clang 中可用?
连续十六进制数字 N3192
带有类型操作数的泛型选择表达式 N3260 Clang 17
往返舍入 N3232
访问字节数组 N3254
消灭一些尘世的恶魔 I N3244
部分Clang 不记录带有寄存器存储类说明符的数组衰减的实现定义行为。Clang 不会诊断在 TU 中没有定义的 extern inline 函数。Clang 接受和拒绝带/不带对齐说明符的重新声明,具体取决于声明的顺序。
支持复杂值的 ++ 和 -- N3259
va_list 的逐字节复制的可使用性 N3262
不完整数组类型的 alignof N3273 Clang 3.5
删除虚数类型 N3274
宏替换的浮点异常 N3286
过时的隐式八进制文字,并添加分隔的转义序列 N3353
'if' 声明,v2 N3356
允许对原子类型进行更严格的对齐 N3312
消灭一些尘世的恶魔 III N3341 未知
消灭一些尘世的恶魔 IV N3342 未知
消灭一些尘世的恶魔 VI N3344 未知
消灭一些尘世的恶魔 VII N3345
消灭一些尘世的恶魔 VIII N3346 未知
引入复数文字 v. 2 N3298
允许对空指针进行零长度操作 N3322
如何对某物加一? N3323
为 SNAN 初始化提供一致的措辞 v3 N3364 未知
案例范围表达式 v3.1 N3370 未知
新的 _Lengthof() 运算符(v4) N3369
命名循环,v3 N3355

C23 实现状态

Clang 支持 C17 之后,非正式地称为 C23 的 C 标准的一些功能。

您可以使用 -std=c23 选项(在 Clang 18 及更高版本中可用)或 -std=c2x 选项(在 Clang 9 及更高版本中可用)在 C23 模式下使用 Clang。

具有支持的特性列表和最低 Clang 版本
语言特性 C23 提案 Clang 中可用?
评估格式 N2186 未知
使 static_assert 与 C++ 协调 N2665 Clang 9
nodiscard 属性 N2267 Clang 9
maybe_unused 属性 N2270 Clang 9
TS 18661 集成
N2314 未知
N2341
N2359
N2546
N2640
N2755
N2931
预处理器行号未指定 N2322
部分与宏调用相关的行号不是调用中宏名称第一个字符的行号。此外,Clang 可能不会将 pp-指令的行号与第一个 # 符号相关联。由于这些是推荐做法,而不是规范性要求,因此 Clang 的行为仍然符合标准。
deprecated 属性 N2334 Clang 9
属性
N2335 Clang 9
N2554 Clang 9
在 offsetof 中定义新类型 N2350
fallthrough 属性 N2408 Clang 9
二进制补码符号表示 N2412 Clang 14
添加 u8 字符前缀 N2418 Clang 15
删除对使用标识符列表的函数定义的支持 N2432 Clang 15
附件 F.8 更新以进行实现扩展和舍入 N2384 未知
_Bool 对 true 和 false 的定义 N2393 被 N2935 替代
[[nodiscard("应该有理由")]] N2448 Clang 10
允许函数定义中使用无名参数 N2480 Clang 11
在复合语句中自由放置标签 N2508 Clang 18
查询属性支持 N2553 Clang 9
二进制文字 N2549 Clang 9
允许重复属性 N2557 Clang 13
诊断文本的字符编码 N2563
我们认为我们保留了什么 N2572 部分
删除混合宽字符串文字串联 N2594 Clang 9
更新为 IEC 60559:2020 N2600 未知
指针与带限定符的数组的兼容性 N2607
部分该提案中的大部分内容都已实现,但 Clang 在 C17 和更早版本中缺乏关于使用不兼容的指针类型的严格诊断,作为一种扩展。此外,Clang 不会正确计算 ?: 运算符的正确结果类型,当结果类型应该是带限定符的数组类型时。
格式说明符与其参数之间的类型关系不明确 N2562 Clang 16
用于独立实现的字符串函数 N2524
数字分隔符 N2626 Clang 13
表中缺少 +(x) N2641
添加对预处理指令 elifdef 和 elifndef 的支持 N2645 Clang 13
[[maybe_unused]] 用于标签 N2662 Clang 16
零比较相等 N2670
负值 N2671
5.2.4.2.2 清理 N2672
走向整数安全 N2683 Clang 18
添加用于 N 位整数的基本类型
N2763 Clang 15
N2775 Clang 15
N2969 Clang 15
N3035 Clang 15
#warning 指令 N2686
无菌字符 N2686
数值相等 N2716
char16_t & char32_t 字符串文字应为 UTF-16 & UTF-32 N2728
IEC 60559 绑定 N2749 未知
__has_include 用于 C N2799
附件 F 溢出和下溢 N2747
从函数参数中的不完整类型中删除 UB N2770
可变修饰类型 N2778
类型没有类型 N2781
5.2.4.2.2 清理(N2672 更新) N2806
允许 16 位 ptrdiff_t N2808
更新 CFP 独立要求的提案 N2823 未知
类型和大小 N2838
澄清整数术语 N2837
最大指数宏的说明 N2843 被 N2882 替代
关于表达式转换的说明 N2846 未知
关于 INFINITY 宏的矛盾 N2848 Clang 19
要求精确宽度整数类型接口 N2872
@、$ 和 ‘ 在源代码/执行字符集中 N2701
NaN 的量子指数(版本 2) N2754 未知
noreturn 属性 N2764 Clang 15
*_HAS_SUBNORM==0 意味着什么? N2797
消除某些复合文字的存储类歧义 N2819
添加不可达控制流的注释 v2 N2826 Clang 17
Unicode 序列超过 21 位是约束违反 r0 N2828 Clang 3.6
使用 Unicode 标准附件 31 的标识符语法 N2836 Clang 15
没有不带原型声明的函数声明符 N2841 Clang 15
删除 _FloatN 类型的默认参数提升 N2844
数值相等/等效的修改建议 N2847
5.2.4.2.2 清理,再次再次(N2806 更新) N2879
char8_t:用于 UTF-8 字符和字符串的类型 N2653 Clang 19
最大指数宏说明更新 N2882 未知
使用 {} 进行一致、无警告且直观的初始化
N2900 Clang 17
N3011 Clang 17
并非那么神奇:typeof
N2927 Clang 16
N2930 Clang 16
修改关键字拼写 v7 N2934 Clang 17
使 false 和 true 成为一等语言特性 v8 N2935 Clang 15
正确地将块定义为语法的一部分 v3 N2937
附件 X(替换附件 H)用于 IEC 60559 交换 N2601
不确定值和陷阱表示 N2861
删除 ATOMIC_VAR_INIT v2 N2886 Clang 17
要求精确宽度整数类型接口 v2 N2888
可变修饰类型的措辞更改 N2992
标识符语法修复 N2939 Clang 15
删除三字母词??! N2940 Clang 18
改进的正常枚举 N3029 Clang 20
放宽对 va_start 的要求 N2975 Clang 16
增强的枚举 N3030 Clang 20
独立 C 和 IEC 60559 一致性范围缩减 N2951 未知
无序函数 N2956
逗号省略和删除(__VA_OPT__) N3033 Clang 12
未完全指定的对象定义 N3006
对象声明的类型推断 N3007 Clang 18
对象定义的 constexpr N3018 Clang 19
为复合文字引入存储类说明符 N3038
标识符主表达式 N3034
引入 nullptr 常量 N3042 Clang 17
联合的内存布局 N2929
改进的标签兼容性 N3037
#embed N3017 Clang 19

C17 实现状态

本版没有重大更改,只有由缺陷报告跟踪的技术修正和澄清。

您可以使用 -std=c17-std=c18 选项(在 Clang 6 及更高版本中可用)在 C17 模式下使用 Clang。

C11 实现状态

Clang 实现了 ISO 9899:2011 (C11) 标准的很大一部分,但各个提案的状态仍在调查中。

您可以使用 -std=c11 选项(在 Clang 3.0 及更早版本中使用 -std=c1x)在 C11 模式下使用 Clang。

具有支持的特性列表和最低 Clang 版本
语言特性 C11 提案 Clang 中可用?
对排序的更细粒度的规范 N1252 未知
表达式的说明 N1282
扩展临时对象的生命周期(分解方法) N1285
要求 signed char 不带填充位 N1310
初始化静态或外部变量 N1311
指针和浮点类型之间的转换 N1316
将 TR 19769 添加到 C 标准库 N1326 Clang 3.3
静态断言 N1330
并行内存排序模型提案 N1349 未知
_Bool 位域 N1356
C1X 的技术勘误 N1359
良性 typedef 重新定义 N1360 Clang 3.1
线程局部存储 N1364 Clang 3.3
常量表达式 N1365 Clang 16
收缩和表达式求值方法 N1367 未知
浮点到 int/_Bool 转换 N1391
宽函数返回(备选提案) N1396
是*除了没有 SSE2 的 32 位 x86 架构,Clang 在所有目标平台上都符合本文档。但是,Clang 在任何平台上都不声称符合 Annex F,并且不打算在该特定目标平台上符合 Annex F,因此无需进行任何更改以符合本文档。
对齐
N1397 Clang 3.2
N1447 Clang 3.2
匿名成员结构体和联合体(模“名称查找”) N1406
类型的完整性 N1439
通用宏机制 N1441
C 内存模型的依赖关系排序 N1444 未知
标准子集 N1460
F.9.2 中的假设类型 N1468 未知
在 C1x 中支持 'noreturn' 属性 N1478 Clang 3.3
基于形式化的 C++ 内存模型更新 N1480 未知
原子类型的显式初始化器 N1482 Clang 4
原子提案(减去三元运算符) N1485
UTF-8 字符串字面量 N1488 Clang 3.3
优化掉无限循环 N1509
Annex G 的条件规范性状态 N1514 (1)
复杂值的创建 N1464 Clang 12
C 和 C++ 扩展标识符字符的建议 N1518 未知
原子 C1x/C++0x 兼容性细化(仅第一部分) N1526
原子位字段实现定义 N1530
对对齐对结构体/联合体类型兼容性的影响的小修复 N1532
宽评估的澄清 N1531 未知
(1): Clang 未实现 Annex G,因此我们通过不定义 __STDC_IEC_559_COMPLEX__ 宏来符合我们的条件支持。

C99 实现状态

Clang 实现了 ISO 9899:1999 (C99) 标准的全部内容。

注意,C99 特性的列表来自 C99 委员会草案。并非所有 C99 文档都公开可用,因此本节中引用的文档可能不准确、未知或未链接。

您可以使用 -std=c99 选项在 C99 模式下使用 Clang。

具有支持的特性列表和最低 Clang 版本
语言特性 C99 提案 Clang 中可用?
通过二元运算符和 <iso646.h> 支持受限字符集 未知
通过有效类型提供更精确的别名规则 未知
受限指针 N448
部分Clang 对 restrict 的支持完全符合标准,但仅被认为部分实现。Clang 实现了 restrict 支持所需的所有约束,但 LLVM 仅支持用于作为函数参数的受限指针的 restrict 优化语义;它不完全支持对局部变量或数据成员的 restrict 的语义。
可变长度数组 N683
灵活数组成员 未知
参数数组声明符中的 static 和 type 限定符 未知
在 <complex.h> 中支持 complex 和 imaginary N693
部分Clang 支持 _Complex 类型说明符,但不支持 _Imaginary 类型说明符。在 C99 中,对 _Imaginary 的支持是可选的,Clang 不声称符合 Annex G。

_Complex 支持需要底层支持库,如 compiler-rt,来提供诸如 __divsc3 之类的函数。在 MSVC 样式的环境中,compiler-rt 不会自动链接。
在 <tgmath.h> 中支持类型通用数学宏 N693
long long int 类型 N601
增加最小翻译限制 N590 Clang 3.2
在 <float.h> 中添加浮点特性 未知 Clang 16
删除隐式 int
N635
N692
N722
可靠的整数除法 N617
通用字符名称(\u 和 \U) 未知
扩展标识符 N717 Clang 17
十六进制浮点常量 N308
复合字面量 N716
指定初始化器 N494
// 注释 N644
在 <inttypes.h> 和 <stdint.h> 中扩展整数类型和库函数 未知
删除隐式函数声明 N636
在 intmax_t/uintmax_t 中完成预处理器算术 N736
混合声明和代码 N740
为选择和迭代语句创建新的块范围 未知
整数常量类型规则 N629
整数提升规则 N725
具有可变数量参数的宏 N707
IEC 60559 支持 未知
部分Clang 支持 Annex F 中的大部分语言要求,但只有在考虑编译器的语言支持、C 运行时库的数学库支持和目标系统的浮点环境支持时才能确定完全符合性。Clang 目前不会在某些转换上引发“无效”浮点异常,也不会为算术常量表达式引发浮点异常,以及其他一些特殊情况。注意,Clang 不定义 __STDC_IEC_559__,因为编译器不完全符合。但是,某些 C 标准库实现(glibcmusl)将定义该宏,无论编译器支持与否,除非编译器定义 __GCC_IEC_559,而 Clang 目前不定义该宏。
此外,Clang 故意不会在没有 SSE2 的 32 位 x86 上符合 Annex F,因为 x87 中浮点运算的行为。
在枚举声明中允许尾随逗号 未知
内联函数 N741
在 <stdbool.h> 中使用布尔类型 N815
幂等类型限定符 N505
空宏参数 N570
添加预定义宏名称 未知
_Pragma 预处理运算符 N634
标准编译指示
N631
N696
__func__ 预定义标识符 N611
va_copy 宏 N671
删除对别名数组参数的弃用 未知
数组到指针的转换不限于左值 N835
放宽对聚合和联合初始化的约束 N782 Clang 3.4
放宽对可移植头文件名称的限制 N772
在返回值的函数中不允许不带表达式的 return 未知

C89 实现状态

Clang 实现了 ISO 9899:1990 (C89) 标准的全部内容。

您可以使用 -std=c89-std=c90 选项在 C89 模式下使用 Clang。