我正在使用 Ubuntu 22.04 进行一些软件开发,并处理二进制数据。我最近发现了
glibc
2.35 版的公告;它指出版本 2.35 包含 二进制转换格式说明符 %b
和 %B
:
- printf 系列函数现在支持 %b 格式的输出 二进制整数,如 ISO C2X 草案中所指定,以及 %B 变体 ISO C2X 草案推荐的格式。
我已经检查了我的
glibc
版本如下,但我不确定这是获取此信息的权威方式:
$ ldd --version
ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
%b
和%B
,但是...大约一个月前,我在这个 Ubuntu 上为微控制器项目安装了 Raspberry Pi C SDK。我在
%b
中使用了二进制格式说明符 %B
和 printf
,如下所示:
printf("\n binary values stored in rcvdata[0]: %#b \n", rcvdata[0]);
printf(" binary values stored in rcvdata[1]: %#b \n", rcvdata[1]);
代码在 Pico 上编译,没有错误或警告,并且输出到我的串行终端(
minicom
2.8)如下:
binary values stored in rcvdata[0]: 0b11111111
binary values stored in rcvdata[1]: 0b11011000
所以是的 - 我可以在我的 RPi Pico C SDK 开发环境中使用二进制格式说明符。
但后来我尝试对使用
printf
编译的小程序使用类似的 gcc
语句以在 Ubuntu 上运行。它运行,但每次使用都会给我 2 个警告:
#include <stdio.h>
int main() {
char data_char = 0x41;
unsigned char u_data_char = 8;
int int_val = -39;
printf("\nSome experiments:");
printf("\nvalue of data_char: %#b", data_char);
printf("\nvalue of u_data_char: %#b", u_data_char);
printf("\nvalue of int_val: %#10b", int_val);
printf("\n\n");
return 0;
}
$ gcc -o printf_binary_3, printf_binary_3.c
printf_binary_3.c: In function ‘main’:
printf_binary_3.c:10:37: warning: unknown conversion type character ‘b’ in format [-Wformat=]
10 | printf("\nvalue of data_char: %#b", data_char);
| ^
printf_binary_3.c:10:12: warning: too many arguments for format [-Wformat-extra-args]
10 | printf("\nvalue of data_char: %#b", data_char);
$ ./printf_binary_3
Some experiments:
value of data_char: 0b1000001
value of u_data_char: 0b1000
value of int_val: 0b11111111111111111111111111011001
我不知道该怎么办:
gcc
会产生警告并状态 unknown conversion type character ‘b’
??[-Wformat-extra-args]
是无法将%b
识别为合法格式说明符的结果??最后 - 谁能解释为什么当编译器说我使用的格式说明符不存在时我得到看似有效的结果,以及如何解决这个问题?
这可能是有用的信息:我在本次问答中了解到,在撰写本文时,二进制说明符的文档还不完整。
结果存在差异的原因是 Raspberry Pi C SDK 使用的 C 库与您的 Ubuntu 系统上的库不同。具体来说,SDK 使用
picolibc
库来为 Pico 目标系统编译代码。这可以解释为什么当目标是 Pico 时您不会收到错误或警告。
OTOH,
glibc
是用于针对 Ubuntu 进行编译的 C 库。这是有点猜测,但我可以想象,由于glibc
支持%b
格式的第一个版本是2.35(您的Ubuntu系统上的版本),之间存在一些未解决的事务 gcc
和 glibc
导致了 警告。我这么说是因为早期版本的glibc
(例如版本2.31)和gcc
(版本10.2.1)在看到%b
中的printf
转换时产生了错误而不是
警告。