A new feature in C2 are bit-offsets.

NOTE: Dont confuse bit-offsets with bit-fields, which are x-bits wide fields inside a struct for memory conservation.

Bit-offsets are used in code that often needs to fetch certain bits from registers, such as driver code.

The syntax of a bit-offset is value[<highest bit>:<lowest bit>].

So the width will be highest - lowest + 1. The syntax was chosen to match hardware specifications that often specify bits in registers in the same way.

func void demo() {
    u32 value = 0x1234;
    u8 a = value[15:8]; // will be 0x12
    u8 b = value[11:4]; // will be 0x23
    u8 c = value[4:0]; // will be the lowest 5 bits

    // Both statements below are equal, the first C style, the second C2 style
    i32 counter = ((value >> 10) & 0x1F);
    i32 counter = value[14:10];
}

Overflows are checked and produce errors, like


u32 value1 = 0xffff;
u8 a = value1[15:0];    // warning{implicit conversion loses integer precision 'u16' to 'u8'}

const u32 Value2 = 0x1234;
i8 b = Value2[6:0] + 100;  // error{constant value 152 out-of-bounds for type 'i8', range [-128, 127]}