5 ms·
>In other words, this snippet of code will do exactly what you expect it to without a single surprise: That reinterpret cast from char* to a char8_t* is undefi
by Kranar 5y ago
>In other words, this snippet of code will do exactly what you expect it to without a single surprise:
That reinterpret cast from char* to a char8_t* is undefined behavior.
std::u8string_view utf8_input(reinterpret_cast<const char8_t*>(argv[1]));
This is not just pedantry either, it was purposely designed this way to allow compilers to better optimize code without worrying about aliasing issues.
Link to the paper which explicitly calls out that char8_t be defined as a new type that does not alias with any other type (hence making that reinterpret cast undefined behavior):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r6.html http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p048...
- 10000truths 5y ago`-fno-strict-aliasing` to the rescue!
- arc-in-space 5y agoThis seems wrong. Regardless of what char8_t is, doesn't char* have a spec-given right to read it? Defining char8_t as a new type is specifically to avoid unnecessarily granting it these all-aliasing powers, but you can still read it as bytes.
- Kranar 5y agoYes, but as I mentioned earlier only char* has the right to read it, in the snippet I posted, it's char8_t* doing the reading.
- moonchild 5y agochar8_t* is allowed to alias char* not because of any special property of char8_t, but because char is allowed to alias any other type (including char8_t).
- Kranar 5y agoAs you said, char* can alias any other type, but that does not allow any other type to alias char*. reinterpret_cast<char*>(T*); // Perfectly fine. reinterpret_cast<T*>(char*); // Undefined behavior. Otherwise it would be trivial for any type to alias any other type: reinterpret_cast<T*>(reinterpret_cast<char*>(U*));
- gpderetta 5y agopedantically, the cast itself is not UB. Dereferencing a pointer which isn't compatible with the dynamic type of the underlying data would be UB, but in this case the actual data is coming from outside the process (the OS usually), and wasn't even necessarily written in C++, so talking about the type of the underlying data is really not well defined (this is similar to reinterpret casting the data coming from read() to whatever is the structure representing the layout of the data). Accessing the data using two different types would be problematic, except that if the other type is char, it is still fine as char is allowed to alias anything. so tldr; as the programmer you can posit that the underlying data is indeed char8_t and the reinterpret cast is valid. You can also read it as char and would still be safe.
- Kranar 5y agoYes, you are correct. That said the dereferencing happens in std::u8string_view's constructor, which will dereference in search of the NULL character to compute the size.