This is an old C programmers trick for binary literals in C and is taken from a posting by Tom Torfs. It is particularly useful in a mixed C/Ada environment because Ada allows binary literals and you may wish to move one or more into C when doing optimisation or other development. The trick is to take a binary literal, pretend it is a hex value and then combine the hex nibbles into binary digits.
This particular version provides link time protection against passing in a non-binary value:
#define BINHEX( X ) ( \ (X & 0xEEEEEEEEuL) \ ? undefined( ) \ : ( ( ( (X * 0x1248uL) & 0xF000F000uL ) * 0x1001 ) >> 24 ) \ ) #define _0b( N ) ( BINHEX(0x##N##uL) )
Note that it works for at most 8 binary digits. To get wider values, just concatenate bytes, as in the following example:
const unsigned long val = (_0b(11111111) << 24) | (_0b(00000000) << 16) | (_0b(10101010) << 8) | _0b(00111100);
Or, probably better, rewrite the _0b macro to take 4 bytes:
#define _0b( N3, N2, N1, N0 ) ( \ BINHEX(0x##N3##uL) << 24 \ | BINHEX(0x##N2##uL) << 16 \ | BINHEX(0x##N1##uL) << 8 \ | BINHEX(0x##N0##uL) \ )
so that you can just write:
const unsigned long val = _0b(11111111,00000000,10101010,00111100);
This compares very nicely with the Ada equivalent:
val : constant UInt32_Type := 2#11111111_00000000_10101010_00111100#;