Search code examples
c++c++14language-lawyerstrict-aliasingstd-byte

Is it possible to backport std::byte to C++14


std::byte is defined in C++17 as:

enum class byte : unsigned char {};

I'm currently stuck at using C++14, and I wonder if I add the same definition in C++14 (in some non-std namespace, along with the operator overloads etc.), will this new type get the same aliasing "free-pass" as an unsigned char or I setting myself up for undefined behavior due to violating the strict aliasing rule?

It seems to work, but I'm wondering if I instead should go with using byte = unsigned char; which sadly causes other complications (for instance then I can't make a difference between a byte and uint8_t).


Solution

  • No, it isn't possible. The aliasing exception is specific only to char, unsigned char and std::byte. You can't define a type in standard C++ to also gain their "superpower".

    There may be compiler-specific attributes that can give a type declared with

    enum class byte : unsigned char {};
    

    equivalent aliasing exceptions, although aliasing isn't the only exceptional behavior either.

    Technically std::byte and unsigned char are also specific exceptions in the core language that are able to provide storage for other objects and the only types that can cause implicit creation of objects when the lifetime of an array of their type starts. Other types can't do either. However, on the usual C++ implementations that part is probably not really all that relevant in practice.

    std::byte and unsigned char (and potentially char) are also the only types for which it is sometimes allowed to operate on indeterminate values in some very specific circumstances. But again, on usual C++ implementations that probably isn't going to be a practical problem.

    There is also an exception for array-new expressions that guarantees specifically only for char, unsigned char and std::byte that there is no offset between the beginning of the allocation and the beginning of the array. Again though, in practice implementations will probably extend this exception to all trivial types.