Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Rant:

Technically, that code invokes undefined behavior as you use `reinterpret_cast` to alias variables. The only standards conforming way (prior to `std::bit_cast`[0] in C++20) was to use `memcpy`.[a] `reinterpret_cast` was added for situations where code you have no control over requires a certain type, but you need to force it to take your variable.[b]

[a]: As `memcpy` (in addition to reinterpreting bits) copies the bits (although a compiler will most likely optimize it out), it doesn’t violate aliasing rules.

[b]: This also requires that the code you give your kludged variable to not read out those bits as what it thinks it is (because aliasing). Kindof pointless because: what’s the point of passing a variable that’s never read?

[0]: https://en.cppreference.com/w/cpp/numeric/bit_cast



memcpy certainly violates aliasing rules. You can access an object as an array of bytes, but you can't memcpy an object to one of a different type and then access it as that type without invoking undefined behavior.


Not true. You actually can. Aliasing is about viewing the same bits as two different types (what `reinterpret_cast`, union-based type punning, and cast pointers do) `memcpy` copies the bits to a new location which doesn’t violate aliasing. I don’t have time to find the reference in the standard, but cppreference.com[0] says it’s ok:

> Where strict aliasing prohibits examining the same memory as values of two different types, std::memcpy may be used to convert the values.

[0]: https://en.cppreference.com/w/cpp/string/byte/memcpy


Who is cppreference.com? The domain registration is concealed, just like that of the other dubious site, cplusplus.com.

I don't see any such a claim about memcpy having magic powers in the N4659 C++ draft.

All it says is that the underlying bytes of an object can be copied to an array of char, unsigned char, or std::byte. Then if that array is copied back into the object, the object subsequently holds its original value.

Anything more about memcpy comes from C by reference, and that would be about the last document on Earth to grant definedness and portability to something like this.


memcpy() by itself cannot violate aliasing rules. By definition, char can alias any object.

Whether you can access an object that has been memcpy()'d into is a separate question. I can't find specific language about this, but I strongly suspect that the result is implementation-defined or unspecified (not undefined), unless there is a possibility of a trap representation.


This remark doesn't appear to add anything to my original unedited comment, which includes the clarifying words "you can't memcpy an object to one of a different type and then access it as that type without invoking undefined behavior".


My reading of section 8.2.1 suggests that it is not UB to copy bytes from an object of one type to an object of another type, and then to read the value of the second object, since it is explicitly allowed to access each object as bytes.


It being well-defined to access an object as an array of bytes doesn't add up to it being well-defined to access a whole object as an lvalue of any type. Type aliasing rules do not work this in this constructive way.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: