I'm using an Ubuntu 22.04 for some software development, and working with binary data. I recently found this announcement for glibc ver 2.35; it states that ver 2.35 incorporates the binary conversion format specifiers %b and %B:
- printf-family functions now support the %b format for output of integers in binary, as specified in draft ISO C2X, and the %B variant of that format recommended by draft ISO C2X.
I have checked my glibc version as follows, but I'm not sure this is the authoritative way to get this information:
$ ldd --version
ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
%b and %B, but...I've installed the Raspberry Pi C SDK about a month ago on this Ubuntu for a micro-controller project. I've used the binary format specifiers %b and %B in printf as follows:
printf("\n binary values stored in rcvdata[0]: %#b \n", rcvdata[0]);
printf(" binary values stored in rcvdata[1]: %#b \n", rcvdata[1]);
The code compiles on the Pico without error or warning, and the output to my serial terminal (minicom 2.8) is as follows:
binary values stored in rcvdata[0]: 0b11111111
binary values stored in rcvdata[1]: 0b11011000
So yeah - I can use the binary format specifiers in my RPi Pico C SDK development environment.
But then I tried to use similar printf statements for a small program I compiled with gcc to run on Ubuntu. It runs, but gives me 2 warnings for each usage:
#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
I don't know what to make of this:
gcc yield warnings & state unknown conversion type character ‘b’ ??[-Wformat-extra-args] is the result of failure to recognize %b as a legitimate format specifier??Finally - can anyone explain why I get what appears to be valid results when the compiler says the format specifier I used doesn't exist, and how to fix this?
And this may be useful information: I learned during this Q&A that the documentation for the binary specifiers is not complete as of this writing.
The reason for the discrepancy in your results is that the Raspberry Pi C SDK uses a different C library than the one on your Ubuntu system. Specifically, the picolibc library is used by the SDK for code compiled for a Pico target system. This would explain why you get no errors or warnings when the target is a Pico.
OTOH, glibc is the C library used for compilations targeted for Ubuntu. This is a bit of a guess, but I can imagine that since the first version of glibc to support the %b format was 2.35 (the version on your Ubuntu system), there was some unsettled business between gcc and glibc that resulted in a warning. I say this because earlier versions of glibc (e.g. ver 2.31) and gcc (ver 10.2.1) produced an error instead of a warning upon seeing the %b conversion in printf, and compile without error or warning w/ glibc ver 2.36 and gcc ver 12.2.
The Raspberry toolkit uses a different C compiler and C library, and seems to support the %b format at runtime (binary output) and compiler time (no warning).
Conversely, on the Ubuntu host, your C library supports the %b format (including the # option) as shown on the output, but the C compiler does not and reports a compile time warning.
The gcc warnings for printf and scanf argument consistency are produced at compile time by the compiler built-in analyser. The compiler does not use the C library for this so it may report a problem where the C library does support an extended format.
This inconsistency should be fixed with a more recent version of gcc, so you should either upgrade your system or install a more recent version of gcc manually. You can also check the behavior of clang.
You can disable these warnings, but they are very useful to avoid stupid mistakes, so you should do this on a case by case basis with pragmas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With