Frequently Asked Questions¶
This document answers some of the often asked questions about bitproto.
Does bitproto depend on endianness ?¶
Yes, bitproto’s wire format is little-endian on every platform. The C library (standard mode) and the C optimization-mode generated code now both produce correct output on big-endian hosts. Python and Go are endian-neutral and were always unaffected. See Endianness for details.
What’s the advantage of this over a bit field ?¶
Bit fields are a standard language feature of C, but almost everything about bit-field is implementation dependent, including the size of them and memory layout. Apart from the endianness issue, the ordering of bitfields in memory is not-portable even between different compilers on the same platform.
Besides, bitproto also targets on Python and Golang, there are no bit fields. If we use bit fields to exchange data between programs in different languages, non-C language users need to write the encoding mechanism manually.
Very interesting to figure out that, bitproto actually encodes the same buffer, when
use bit fields with structures setting no paddings in C. For instance, the buffer s
in the C program below is the same with the encoded buffer of the bitproto message Data
following:
struct Data {
uint8_t a : 3;
uint8_t b : 3;
uint8_t c : 5;
uint8_t d : 7;
} __attribute__((packed, aligned(1))); // this line matters
struct Data d = {1, 5, 28, 70};
unsigned char *s = (unsigned char *)(&d);
message Data {
uint3 a = 1
uint3 b = 2
uint5 c = 3
uint7 d = 4
}
Even so, it’s recommend to use bitproto over bitfields. It’s compiler independent, cross-multiple-languages and can support extensiblity.
Is it safe to use bit-level unsigned integers ?¶
What if the value assigned overflows an unsigned integer type at runtime?
Say what if I assign 9 to an uint3 ?
It’s very safe for enums, the bitproto compiler checks overflows at compile-time.
enum Color : uint3 {
// The bitproto compiler will report error here.
COLOR_OVERFLOW = 18
}
But it’s different for uint{n} used in a literal way, you have
to ensure the value fits the bit space by yourself, bitproto won’t check
boundaries at runtime:
message Data {
uint3 value = 1
}
struct Data d = {};
// No error will be reported here.
// Having to ensure it's safe by yourself.
d.value = 18;