Is it possible to backport std::byte to C++14
Asked Answered
O

2

5

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).

Offshore answered 9/8, 2023 at 9:17 Comment(8)
I think it should be OK because enum can be reinterpret to the underlying type and unsigned char gets the free-pass.Aldas
or just replace your current byte type with std::uint8_tClingfish
I like to use the byte name because I think it makes the API easier to read. part of my problem is that std::byte is explicitly mentioned in the C++17 standard in places where char and unsigned char are mentioned in relation to aliasing, similar to how it is done here: en.cppreference.com/w/cpp/language/…Offshore
You could have exactly the same definition in your own namespace. std namespace is not allowed to be extended apart from specialising templates from.Suellen
@Suellen I think the real question here is whether or not an enum class follows the same aliasing rules as its underlying type or whether compiler magic is used for std::byte.Higginbotham
I haven't ever seen much use in anyway, it suffers from the same problems as signed, unsigned or bare char: It's bit size can vary across architectures… I personally rather stick to uint8_t – it will not exist on systems without an appropriate type to be mapped to, so you are hinted to necessary special handling on such platforms immediately.Suellen
@Higginbotham Enum and underlying type share the same alignment requirements/rules. You mean that's not clear anyway?Suellen
@Suellen Unfortunately aliasing isn't just about alignment, it includes assumptions the compiler is allowed to make when generating code. So the same alignment isn't enough make aliasing legal.Higginbotham
R
7

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.

Rms answered 9/8, 2023 at 10:28 Comment(1)
In particular, the restrictions on which array types can provide storage are unlikely to be exploited by a C++14 compiler because C++14 never spelled out any such restrictions in the first place.Balcom
F
0

The C++ Standard does not impose any normative requirements upon programs, despite the phraseology used in much of it (From section 4.1.1: Implementation compliance: General):

Although this document states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:

... If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program.

Although C14 does not require that implementations provide a practical means of supporting the described functionality, nearly all implementations can be configured to extend the semantics of the language to support such functionality in consistent fashion. Clang and gcc both use the -fno-strict-aliasing flag for that purpose. Unless one has a particular need to use a compiler which does not support such extensions, using such extensions when performing tasks that benefit them is apt to be safer than compiling without them even if one jumps through hoops to ensure that any bug-free compilers would be required to process one's code correctly.

Foundling answered 9/8, 2023 at 21:9 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.