4 ms·
> E.g. you can't memcpy a uint64 to a double and expect well-defined behavior. Yes, you can. The behavior is implementation-defined but not undefined. (Well,
by comex 8y ago
> E.g. you can't memcpy a uint64 to a double and expect well-defined behavior.
Yes, you can. The behavior is implementation-defined but not undefined. (Well, it can trigger undefined behavior if the value corresponds to a signaling NaN, or if the implementation uses a nonstandard, non-IEEE format for doubles that has other "trap representations". But it's not otherwise undefined.)
The basis for this is that the aliasing rule has an explicit exception for reading or writing to objects using char pointers, i.e. byte-by-byte, regardless of the object's type. This exception is in both the C standard:
https://port70.net/~nsz/c/c11/n1570.html#6.5p7 https://port70.net/~nsz/c/c11/n1570.html#6.5p7
and the C++ standard:
http://eel.is/c++draft/expr.prop#basic.lval-11.8 http://eel.is/c++draft/expr.prop#basic.lval-11.8
The memcpy function is defined as copying characters, so the exception applies to it too.
Both standards also explicitly define that objects (at least of POD types) have byte representations and those representations are implementation-defined (as opposed to triggering undefined behavior if you depend on them). For C:
> Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.
https://port70.net/~nsz/c/c11/n1570.html#6.2.6.1 https://port70.net/~nsz/c/c11/n1570.html#6.2.6.1
C++:
http://eel.is/c++draft/basic.types http://eel.is/c++draft/basic.types
- kazinator 8y ago"access" refers to reading there. Not reading or writing. Objects may be treated as arrays of character type to the extent that their value may be examined that way. If you memcpy a uint64_t to a double, the implementation is not required to notice that the double variable's value has changed; a subsequent access to that variable can continue to refer to a register. It's not a matter of what bit pattern was stored there.
- comex 8y agoNo, "access" is defined as reading or writing: > 3.1 > 1 access >〈execution-time action〉 to read or modify the value of an object Thus, the requirement is symmetrical. The compiler must consider any char write as potentially aliasing a subsequent read (or write) of any type, unless it can prove non-aliasing without depending on type. And similarly, it must consider a write of any type as potentially aliasing a subsequent char read/write.