1

The type std::byte comprises CHAR_BIT bits, and that may be more than 8.

So, how do I declare a true octet in C++?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
wimalopaan
  • 4,838
  • 1
  • 21
  • 39
  • 1
    [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset)? Not sure what you mean by "true" octet – Mat Aug 17 '23 at 09:25
  • [`std::byte`](https://en.cppreference.com/w/cpp/types/byte) is defined as `enum class byte : unsigned char {};` So, why can't you define `enum class octet : std::uint8_t {};` then? – heap underrun Aug 17 '23 at 09:25
  • 1
    If your compiler/hw support true octet then (u)int8_t types will be declared. If there is no such declaration in [](https://en.cppreference.com/w/cpp/types/integer) then probably there is no 8-bit memory access in your HW but it is really unlikely – Konstantin T. Aug 17 '23 at 09:26
  • 3
    `CHAR_BIT` is still the smallest size available, so if it is 9, there just isn't any 8-bit types on that machine. I would add a `static_assert` and not bother with support for the oddest hardware. – BoP Aug 17 '23 at 09:28
  • 2
    out of curiosity, are you working on a system where `CHAR_BIT` is not `8`? And do you need there a byte that has `8` bits? – 463035818_is_not_an_ai Aug 17 '23 at 09:28

1 Answers1

7

If the hardware supports 8-bit integers with no padding, then std::uint8_t will be defined, and could be used for that purpose.

enum class octet : std::uint8_t {};

// add bitwise ops similar to the operator overloads for std::byte
// alternatively, use std::uint8_t directly

However, this is basically pointless. If unsigned char is wider than 8 bits, then std::uint8_t won't be defined because no type can be smaller than a byte in C++.

Any "true octet" type is either not going to be portable, or it will require padding. If padding is acceptable, you can define it as follows:

enum class octet : std::uint_least8_t {};

constexpr bool operator==(octet x, octet y) noexcept {
    return (unsigned(x) & 0xff) == (unsigned(y) & 0xff);
}

// TODO: implement other comparisons

constexpr octet operator|(octet x, octet y) noexcept {
    return octet(unsigned(x) | unsigned(y));
}

constexpr octet operator<<(octet x, std::integral auto s) noexcept {
    return octet((unsigned(x) << s) & 0xff);
}

// TODO: implement other bitwise ops, and possibly arithmetic ops

Also, as commenters have pointed out, hardware with no support for 8-bit types is extremely rare. Unless you expect to compile your code for digital signal processors (DSPs) or other unusual hardware, just assume 8-bit bytes. Use std::uint8_t, or

static_assert(CHAR_BIT == 8);
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
  • I think that`uint_least8_t` maybe also greater than 8 Bit on plattforms where `char` > 8 bits. – wimalopaan Aug 17 '23 at 10:14
  • 2
    @wimalopaan yes, which means that `octet` would be greater than 8 bits in size. However, it behaves like an octet because operator overloads bit-mask it with `0xff` so that only the lowest 8 bits are considered. It's impossible to define types smaller than byte, but it's possible to define types that behave as if they were smaller than a byte. – Jan Schultke Aug 17 '23 at 10:16
  • Ok, I missed your edits. – wimalopaan Aug 17 '23 at 10:47