I was thinking again about Bas' addition of bit fields in such a nice way into the system. I have some code that implements a fairly ugly protocol (industrial control systems) and there are few bit fields, but the endian-ness of the bytes in the words is very important.
I have lots of little inline (type safe and the compilers generally do smart things with them) functions that convert the values back and forth between host and target endian types.
Given that I am looking at this kind of code a lot right now, I thought about things that would make my life a lot easier for low level hardware and protocol support.
- add keywords for designating endian-ness. i.e. new "little" and "big" keywords that would be used in places where you also use unsigned or volatile today.
- bit structs
C is pretty good at handling bytes. With packed structs, you can do a lot, but you still have to handle endian problems manually.
foo: int32 little_endian;
bar: uint16 big_endian;
Many hardware systems are controlled by bit fields and those fields may be big or little endian. Some (there are engineers who probably need to rethink some of their designs) have both :-(
How about a "bitstruct"?
bitstruct [160] {
control: integer [0..30];
clear_interrupts: integer [31..31];
command: integer [32..37];
ugly_field: integer [38..42,49..53];
...
}
The array-like statement [160] defines the number of bits. Fields within the bitstruct specify where the field is in the bits.
It is common enough, though thankfully not that common, for some fields to be split into two or more sections. I showed that with the "ugly_field" example. I have seen cases where the most significant bits are before the least significant bits. In that case we'd have something like:
ugly_field: integer [49..53, 38..42];
Ugly!
I am not sure how you would want the little_endian and big_endian keywords to work here. Maybe you would specify it with the bit ranges like in ugly_field?
I just thought I would throw that out there.
Best,
Kyle