Inserting binary values into C

This is an old C programmers trick for binary literals in C and is taken from a posting by Tom Torfs (http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f?p...). 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) 

Or, probably better, rewrite the _0b macro to take 4 bytes:

#define _0b( N3, N2, N1, N0 ) (                 \
     BINHEX(0x##N3##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#;

Comments

It's great to have portable code, but it's also useful to know that many compilers (GCC for example) have extensions to include binary literals.

i = 0b101010;