-1

Unsing MS Studio 2022 I am trying to pack two items into a union of size 16 bits but I am having problems with the correct syntax.

The first item is an unsigned short int so no problems there. The other is an array of 5 items, all two bits long. So imagine:

enum States {unused, on, off}; 
// Should be able to store this in a 2 bit field

then I want

States myArray[5]; 
// Should be able to fit in 10 bits and 
// be unioned with my unsigned short

Unfortunatly I am completely failing to work out the correct syntax which leads to my array fitting into 16 bits. Any ideas?

timrau
  • 22,578
  • 4
  • 51
  • 64
  • 1
    Each element of the array must have its own address, so each element must occupy at least one byte. Maybe you want to use bit-fields instead of enum arrays? – user17732522 Feb 25 '22 at 12:51
  • _MS Stdio 2022_: you mean _Visual Studio 2022_? – Jabberwocky Feb 25 '22 at 12:54
  • C++ does not support arrays of bit-fields. You can declare a struct with five bit-fields 2 bits long each, but you won't be able to access them *by indexing*. –  Feb 25 '22 at 13:22
  • You could define a class template to hold an array of "bitfields", similar to `std::vector`. That won't be true C++ bitfields, though. And there's no direct way to find out how many bits you need per State, although you could derive that from `unused` and `off`. – MSalters Feb 25 '22 at 13:39

1 Answers1

1

You can't do that. An array is an array, not some packed bits.

What you can do is using manual bit manipulation:

#include <iostream>
#include <cstdint>
#include <bitset>
#include <climits>
enum status {
    on = 0x03,
    off = 0x01,
    unused = 0x00
};
constexpr std::uint8_t status_bit_width = 2;


std::uint16_t encode(status s,std::uint8_t id, std::uint16_t status_vec) {

    if(id >= (CHAR_BIT * sizeof(std::uint16_t)) / status_bit_width) {
        std::cout << "illegal id" << std::endl;
        return status_vec;
    }
    std::uint8_t bit_value = s;
    status_vec |= bit_value << (id*status_bit_width);
    return status_vec;
};

int main(void) {
    std::uint16_t bits = 0;
    bits = encode(on,1,bits);
    std::cout << std::bitset<16>(bits) << std::endl;
    bits = encode(off,2,bits);
    std::cout << std::bitset<16>(bits) << std::endl;
    bits = encode(unused,3,bits);
    std::cout << std::bitset<16>(bits) << std::endl;
    bits = encode(off,4,bits);
    std::cout << std::bitset<16>(bits) << std::endl;
    bits = encode(off,7,bits);
    std::cout << std::bitset<16>(bits) << std::endl;
    bits = encode(on,8,bits);
}
Raildex
  • 3,406
  • 1
  • 18
  • 42