Q: "[W]hich platforms/C-standard-library implementations support "%b"? And - can I test for this support?"
A: glibc has supported %b integer conversion since version 2.35.
I don't have a list of which C libs support %b and which do not. I know that glibc (post ver 2.35) does, and I know that the picolibc does because I use them (i.e. I'm not a know-it-all :)
As far as testing, I guess there are two ways:
- For
glibc, check the version as follows; e.g.:
ldd --version
ldd (Debian GLIBC 2.36-9+rpt2+deb12u3) 2.36
...
- For other C libraries, perhaps the best way is to compile a simple application in your preferred development environment; e.g.:
#include <stdio.h>
int main() {
int int_val = 39;
printf("binary value of int_val: %#b \n", int_val);
// ANSWER: int_val = 0b100111 ; note no leading zeros
}
Answer from Seamus on Stack Overflow
The people coming up with the next C language standard are proposing new printf() format specifiers %b and %B, to output integers as binary literals, i.e. 0b00010110, the binary representation of 22.
The section of the Bash manual describing the builtin printf command references the manual for the external printf program, printf(1); which itself references the manual for the C function printf(), printf(3). The Bash builtin printf command supports a bunch of C-language printf() format specifiers, so they just direct you to that documentation to see how those work.
However, the Bash builtin printf supports additional format specifiers, beyond those supported by the C-language printf(). One of those is %b, which in the case of Bash's printf, currently "causes printf to expand backslash escape sequences in the corresponding argument in the same way as echo -e."
A number of people from the Austin Group, the people behind the POSIX specification, emailed in to the bug-bash email list, where Bash development discussion takes place, saying that they would like a new POSIX standard to change the mandated behavior of the %b format specifier used by the command-line printf command, whether that's an external program or the Bash builtin, to mirror the behavior of this format specifier as used by the C printf() function in the upcoming C standard. They are recommending %#s, signifying an alternative string format, to take over the duties of the current %b. They do seem to be saying that they'd only change the standard in this way if they get buy-in from shell authors, though.
Chet Ramey, the Bash maintainer, really wasn't having it:
I don't have a problem adding %#s. I have a problem with POSIX not seeing that the printf builtin is not a direct parallel to the library function and forcing an incompatible change.
So, do scripts you write or maintain use the %b printf format specifier? What's your take on all this?
c - printf's missing binary format specifiers: `%b` and `%B` - Stack Overflow
What is the format specifier for binary in C? - Stack Overflow
Format specifiers in C
(Newbie) question pertaining C : format specifier "%pc"
What happens if the format specifier does not match the data type?
Can I use format specifiers for string manipulation in C?
What are some common errors when using format specifiers in C with examples?
Videos
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.
UPDATE: As of C23, the below function is no longer required. New format specifiers %b and %B have been added to printf() and friends to format integers as binary numbers—the former omitting any leading zeros and the latter including them (similar to %x and %X).
Original answer:
The reason you're having trouble finding a format specifier for printing integers in binary is because there isn't one. You'll have to write you're own function to print numbers in binary.
So for a single unsigned byte:
#include <stdio.h>
#include <limits.h>
void print_bin(unsigned char byte)
{
int i = CHAR_BIT; /* however many bits are in a byte on your platform */
while(i--) {
putchar('0' + ((byte >> i) & 1)); /* loop through and print the bits */
}
}
And for a standard unsigned int:
#include <stdio.h>
#include <limits.h>
void print_bin(unsigned int integer)
{
int i = CHAR_BIT * sizeof integer; /* however many bits are in an integer */
while(i--) {
putchar('0' + ((integer >> i) & 1));
}
}
Adjust the function for larger integers accordingly. Be wary of signed shifting though because the behavior is undefined and entirely compiler dependent.
There isn't one. If you want to output in binary, just write code to do it.
Hello, I am currently learning C and I was wondering what the point of format specifiers are. I understand what they do, but what is the point? If you declare a variable to be a float, why do you also have to specify the format in the printf() function? Isn't it still a float?
Thanks!