ARTICLE AD BOX
Some compilers may just look to see if the type is an enum declared in the std namespace named byte (e.g., https://github.com/llvm/llvm-project/blob/98e26bcd03d680c9525aaff9132a543f5bd8dc51/clang/lib/AST/Type.cpp#L3311).
GCC and Clang both support the may_alias attribute to give a similar effect to std::byte/unsigned char (in that it 'may alias' any other object of any type), which can be used like:
namespace my_std { enum class [[gnu::may_alias]] byte : unsigned char {}; }Example of difference: https://godbolt.org/z/jPbq7EPTe
#include <cstddef> namespace my_std { enum class [[gnu::may_alias]] byte : unsigned char {}; enum class nonaliasing_byte : unsigned char {}; } template<typename B> bool f(int& x, B& b) { int read = x; b = {}; return x == read; } template bool f(int&, std::byte&); // Compiles to: read, write, read, compare template bool f(int&, my_std::byte&); // Compiles to: read, write, read, compare template bool f(int&, my_std::nonaliasing_byte&); // Compiles to: write, return trueMSVC does not implement strict aliasing, so the attribute is simply ignored and this byte class will work as intended.
If you are not using GCC, Clang or MSVC, you should consider finding a different standard library that works with your compiler without exceptions, or "make your own standard library":
// <cstddef> #include <stddef.h> namespace std { // Consult your compiler for if this is the correct implementation enum class byte : unsigned char {}; }Two other properties that std::byte has that your my_std::byte does not have is implicit object creation (my_std::byte arr[N] does not implicitly create objects) and propagation of indeterminate/erroneous values:
https://godbolt.org/z/Mo3rn33nh / [basic.idet]
#include <cstddef> #include <bit> namespace my_std { enum class [[gnu::may_alias]] byte : unsigned char {}; } template<typename B> constexpr bool f() { unsigned char c; B b = std::bit_cast<B>(c); return true; } static_assert(f<unsigned char>()); static_assert(f<std::byte>()); // static_assert(f<my_std::byte>()); // Fails to compile, the indeterminate value becomes UBBut you can use unsigned char to implicitly create objects / have indeterminate values, then alias those unsigned chars with the [[may_alias]] my_std::byte.
