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 | 未知 |
__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 标准库实现(glibc、musl)将定义该宏,无论编译器支持与否,除非编译器定义 __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。