✊技术前瞻者——C23标准进展与主要特性简介

作为一门基础语言,C已经走过了很多年。从最初的K&R C,到ANSI C、C99、C11、C17,C语言也在不停的与时俱进。现在,下一代标准C23即将到来,让我们提前了解会带来哪些新的特性吧!👴 ✊ ❕

N2645 - #elifdef and #elifndef

如果你曾这样写预编译宏:

#ifdef FOO
	/* stuff if there is a defined FOO */
#elifdef BAR
	/* stuff if there is a defined BAR */
#elifndef BAZ
	/* stuff if there is NO defined BAZ */
#else
	/* stuff as the last resort */
#endif

然后将产生报错,这个提案就是针对此种情况。它扩展了#ifdef/#ifndef,使其在#elif中也有对应的形式。

N2626 - 数字分隔符

假如用到8314056565186323712ull作为一个数字常量,当我们一遍又一遍地读它的时候,是否感觉到眼睛要看花了?或者要制作复杂的二级制bit数据块(把它分成字节,或者半字)时,你是否想让它更容易阅读?现在可以了!本提案建议增加:数字分隔符——',使用如下:

const unsigned magical_number = 1'633'902'946;

C23也将此特性用于二进制整数字节值,因此,同样的数字也可以用更精确的二进制分组写出:

const unsigned magical_number = 0b0110'0001'0110'0011'0110'0001'0110'0010;

看起来是不是很棒!而且它还与C++的语法相匹配。

N2630 - 二进制整数的格式化输入/输出

本提案允许我们使用"%b"格式符。这对二进制文本的解析是有意义的。它适用于scanfstrto*,以及printf系列函数。小警告:因为一些第三方实现已经用到了"%B"/"%#B"格式符,因此对这两种情况提案没有规定对应的打印规范。"%#B",它会用大写字母打印前缀,"%B"完全没有!所以就需要程序员自己好好处理一下"0B%b"的情况。

N2680 - 特定宽度长度修饰符

特定宽度长度修饰符是对一个看起来非常简单的问题的提议,不幸的是,这个问题没有一个简单的答案。“我如何安全地打印任意大小的整数?”最初,答案是printf("%j", (intmax_t)any_integer_ever);。不幸的是,ABI使得实现有了高效的处理指令。(u)int128_t(u)int256_t可以提升为通用算术类型语法的整数类型,我们不能更改intmax_t在现有平台上的定义。实际上,(unsigned) long long到下一次大的架构升级的定义还是未知的,例如x86_64,“i128tanium”或者其他什么?(i128tanium不是真实的架构,我们在这里想象)。但这提出了一个安全性和可移植性问题:如何针对各个芯片架构打印建议类型的整数类型?

本提议带来的解决方案是printf("%w128d", my_128bit_integer);。现在可以将整数类型的位数准确地传递给格式化程序。注意,这也意味着你可以使用它来打印int时只读取低位,例如使用printf("%w8d", 0xFEE);。这为我们提供了一种跨平台的方法来处理具有给定实现的位,并将其正确地打印出来!它还保证是安全的:如果整数支持格式化这样一个特定大小的整数,那么它将正确地进行格式化(否则,它将出错,就像通常使用未知格式字符串时一样)。

N2709 - 新增N-位整数基本类型

C23将考虑用_BitInt(N)定义N位整数。以往C语言的整数类型,像int的位数是未知的,它与编译器和芯片架构相关。这是一个非常大的改变,特别对于嵌入式或底层硬件工程师来说。
一个低位数和高位数的整数相操作,那么低位数的整数将转换成高位数。如_BitInt(22)_BitInt(4)型的两个数据相加,结果将是_BitInt(22)。默认是带符号位的,可以用前缀unsigned来声明成无符号数。

N2686 - #warning指令

你有没有想过在编译代码时提示一些告警信息?例如,打印“hey, this thing might go wrong, it might not, just letting you know” 来指示一些可能出错的地方,或者在用户编译调用到的库时打印“ “hey, you’re doing great, keep it up, love you!”。C23将通过增加#warning指令来帮助实现上述想法。它不会终止编译过程,但会通过提示警告信息帮助开发者注意一些可能出错或需要改进的地方。

N2799 - __has_include

令人遗憾的是,很多预处理功能(如__VA_OPT__and __has_include)都是C++率先支持,虽然C开发者更依赖这些预处理功能。现在,这些已经提到C23的日程表上了,并且,__has_include已经成为了C23标准的一部分。它允许我们检查一个头文件是否存在,如果预处理器能找到指定的头文件,在计算结果是1(true),否则为0(false)。例如:

#if __has_include("example.h")
#include "example.h"
#else
#error "cannot find example.h"
#endif

int main() {}

这意味着用C编写健壮、独立的库变为可能,这些库不需要大量的预先适配工作才能在许多完全正常的系统上开始工作。

其它

还有很多其它小的改动,这是我整理的C23比较大的一些改进,其它还有像内存安全、前向声明参数,指定枚举的基础类型等。C语言标准的改进不像C++、Rust等,它是一次一个提议进行讨论确定的。但总体来说,C语言也在不停的与时俱进,以变得更加安全高效!
好了,如果你喜欢本文,希望能点个赞。关注我,将分享更多技术文章!💚

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Roc大鹏君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值