C23 杂记

发布: (2026年1月4日 GMT+8 00:00)
5 min read
原文: Dev.to

Source: Dev.to

介绍

我已经在C23中针对各个新特性写了几篇文章,涵盖了属性auto链接)、bool链接)、用于复合字面量的存储类、constexpr链接)、枚举的显式底层类型enumerationsnullptr链接)以及typeof链接)。还有一些零散的新特性不足以单独成文,因此本文将把它们一起讨论。

聚合初始化

您现在可以使用空的 = { } 来初始化聚合(数组、结构体和联合)。以前必须在大括号之间至少包含一个 0

二进制字面量

自 C 诞生以来,C 已经拥有十进制、八进制和十六进制整数字面量。C23 从 C++14 采用了二进制字面量,使用 0b0B 前缀:

int n = 0b101010;  // 42 decimal

_BitInt

新增了一种 位精确整数 类型,记作 _BitInt(n),其中 n 是正的常量整数表达式。它可以是有符号(默认)或 unsigned。 (如果是有符号,则 n 包含符号位。)一些示例:

unsigned _BitInt(24)  rgb24;   // 24‑bit RGB 颜色
unsigned _BitInt(256) sha256;  // SHA‑256

n 的最大取值由实现决定,但至少与 unsigned long long 的位数一样多。

十进制浮点类型

虽然它们作为扩展已经存在一段时间,但新的十进制浮点类型 _Decimal32_Decimal64_Decimal128 现在已正式受支持。

十进制浮点类型更适合涉及金钱(美元、欧元、英镑等)的计算,因为它们不受标准浮点类型的舍入误差影响。标准浮点类型仍然是一般浮点计算的首选。

标签后的声明

现在可以在 gotocase 标签后立即放置声明:

error:             // C < C23: error; C23: OK
    int code;

以前,你必须使用一种技巧,例如在冒号后加一个空语句 (:;) 才合法。C 委员会本应在 C99 允许声明与代码交错时就把这项改为合法,但迟做总比不做好。

数字分隔符

C23 也从 C++14 中采用了 ' 字符作为数字分隔符,以提升可读性:

int n = 0b0010'1010;
int c = 299'792'458;

整体数值保持不变;你可以随意对数字进行分组。不能使用逗号,因为逗号已经用于分隔函数参数并充当 逗号运算符

K&R‑风格函数

尽管函数原型在 C89(首个 ANSI C)时已从 C++ 中引入,C 仍然支持 “K&R 风格” 的函数声明和定义:

char* strncpy();  // C < C23: unspecified arguments

char* strncpy( dst, src, n )
    char *dst;
    char const *src;
    size_t n;
{
    /* ... */
}

C23 已经不再支持此类声明和定义。

New Keyword Spellings

除了 bool 替代 _Boolalignas 替代 _Alignasalignof 替代 _Alignofstatic_assert 替代 _Static_assert,以及 thread_local 替代 _Thread_local,旧的拼写仍然受支持,但已被弃用。

新的预处理指令

预处理器现在包括 #elifdef#elifndef#embed#warning 指令。

未命名的未使用参数

在历史上,C 语言要求未使用的参数必须命名,常用的消除“未使用”警告的方法是将参数强制转换为 void

char** cdecl_rl_completion( char const *text,
                            int start, int end ) {
    (void)end;  // unused
    /* ... */
}

在 C23 中,你可以直接省略参数名,就像在函数声明中一样。

__VA_OPT__

虽然它已经被 GCC 和 Clang 作为扩展支持了一段时间,但 __VA_OPT__ 现在已经成为 C 标准的一部分。

可变参数函数

正如前文所述,可变参数函数不再需要至少一个必需参数;你可以这样写:

void f( ... ) {      // C23: no required parameter
    va_list args;
    va_start( args );  // C23: no second argument
    /* ... */
}

此特性来源于 C++。

结论

在 C23 的所有改动中,auto 可能是使用最广的;但其他改动虽然不具革命性,却也很不错(有时甚至早该出现了)。

Back to Blog

相关文章

阅读更多 »

C 是最好的

抱歉,我没有看到您提供的具体摘录或摘要内容,请您提供需要翻译的文本,我将为您翻译成简体中文。

C++ 说 “我们在家尝试”。

许多具有异常机制的语言¹也都有 finally 子句,所以你可以这样写: cpp try { // ⟦ stuff ⟧ } finally { always; } 快速检查表明,这种 co…