printf 缺少二进制格式说明符:`%b` 和 `%B`

7 c printf glibc type-conversion

我正在使用 Ubuntu 22.04 进行一些软件开发,并处理二进制数据。我最近发现了2.35 版本的公告glibc;它指出版本 2.35 合并了二进制转换格式说明符 %b和%B:

\n
\n
    \n
  • printf 系列函数现在支持以二进制形式输出\n整数的 %b 格式(如 ISO C2X 草案中所指定),以及 ISO C2X 草案推荐的该格式的 %B 变体。
  • \n
\n
\n

我已glibc按如下方式检查了我的版本,但我不确定这是获取此信息的权威方式:

\n
$ ldd --version\nldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35\n
Run Code Online (Sandbox Code Playgroud)\n

看来我可以使用二进制格式说明符%b和%B,但是......

\n

大约一个月前,我在这个 Ubuntu 上为一个微控制器项目安装了Raspberry Pi C SDK 。我使用了二进制格式说明符%b,%B如下printf所示:

\n
    printf("\\n  binary values stored in rcvdata[0]: %#b \\n", rcvdata[0]);\n    printf("  binary values stored in rcvdata[1]: %#b \\n", rcvdata[1]);\n
Run Code Online (Sandbox Code Playgroud)\n

代码在 Pico 上编译时没有错误或警告,并且我的串行终端(minicom2.8)的输出如下:

\n
  binary values stored in rcvdata[0]: 0b11111111 \n  binary values stored in rcvdata[1]: 0b11011000 \n
Run Code Online (Sandbox Code Playgroud)\n

所以是的 - 我可以在我的 RPi Pico C SDK 开发环境中使用二进制格式说明符。

\n

但后来我尝试对我编译的在 Ubuntu 上运行的printf小程序使用类似的语句。gcc它运行,但每次使用都会给我两个警告:

\n

代码:

\n
#include <stdio.h>\n\nint main() {\n\n    char data_char = 0x41;\n    unsigned char u_data_char = 8;\n    int int_val = -39;\n\n    printf("\\nSome experiments:");\n    printf("\\nvalue of data_char: %#b", data_char);\n    printf("\\nvalue of u_data_char: %#b", u_data_char);\n    printf("\\nvalue of int_val: %#10b", int_val);\n    printf("\\n\\n");\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译输出(部分):

\n
$ gcc -o printf_binary_3, printf_binary_3.c\nprintf_binary_3.c: In function \xe2\x80\x98main\xe2\x80\x99:\nprintf_binary_3.c:10:37: warning: unknown conversion type character \xe2\x80\x98b\xe2\x80\x99 in format [-Wformat=]\n   10 |     printf("\\nvalue of data_char: %#b", data_char);\n      |                                     ^\nprintf_binary_3.c:10:12: warning: too many arguments for format [-Wformat-extra-args]\n   10 |     printf("\\nvalue of data_char: %#b", data_char);\n
Run Code Online (Sandbox Code Playgroud)\n

执行结果:

\n
    printf("\\n  binary values stored in rcvdata[0]: %#b \\n", rcvdata[0]);\n    printf("  binary values stored in rcvdata[1]: %#b \\n", rcvdata[1]);\n
Run Code Online (Sandbox Code Playgroud)\n

我不知道该怎么做:

\n
    \n
  • 为什么会gcc产生警告和状态unknown conversion type character \xe2\x80\x98b\xe2\x80\x99?
  • \n
  • 我猜警告是[-Wformat-extra-args]由于无法识别%b为合法格式说明符而导致的?
  • \n
\n

最后 - 谁能解释为什么当编译器说我使用的格式说明符不存在时我得到看似有效的结果,以及如何解决这个问题?

\n

这可能是有用的信息:我在本次问答中了解到,截至撰写本文时,二进制说明符的文档还不完整。

\n

Sea*_*mus 1

结果存在差异的原因是Raspberry Pi C SDK使用的 C 库与 Ubuntu 系统上的库不同。具体来说,picolibcSDK 使用该库来为 Pico 目标系统编译代码。这可以解释为什么当目标是 Pico 时您不会收到错误或警告。

OTOHglibc是用于针对 Ubuntu 进行编译的 C 库。这有点猜测,但我可以想象,由于glibc支持该%b格式的第一个版本是 2.35(Ubuntu 系统上的版本),因此之间存在一些未解决的业务gcc,从而glibc导致了警告。我这么说是因为早期版本的glibc(例如版本 2.31)和gcc(版本 10.2.1)在看到中的转换时产生了错误而不是警告,并且在版本 2.36 和版本 12.2 中编译时没有错误或警告。%bprintfglibcgcc