I have difficulty to understand the portability of bit fields in C. Imagine I have a shared library composed of only two files, libfoobar.h
(the public header) and libfoobar.c
, with the following simple content:
libfoobar.h
:
typedef struct some_bitfield_T {
unsigned char foo:3;
unsigned char bar:2;
unsigned char tree:2;
unsigned char window:1;
} some_bitfield;
extern unsigned int some_function (some_bitfield input);
libfoobar.c
:
#include "libfoobar.h"
unsigned int some_function (some_bitfield input) {
return input.foo * 3 + input.bar + input.tree + 1 - input.window;
}
After having compiled and installed the library, I test it with a program named test
.
test.c
:
#include <stdio.h>
#include <libfoobar.h>
int main () {
some_bitfield my_attempt = {
.foo = 6,
.bar = 3,
.tree = 1,
.window = 1
};
unsigned int some_number = some_function(my_attempt);
printf("Here is the result: %u\n", some_number);
return 0;
}
Is there any possibility that the test
program above will produce anything different than the following output?
Here is the result: 22
If yes, when? What if the library is compiled by someone else other than me? What if I use different compilers for the library and the test
program?
Bitfields are implementation defined and not not portable. But for most relevant platforms, their extraction/packing is well specified by the ABI so that they can be safely used in shared libraries.
E.g.: