https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114217
Fangrui Song <i at maskray dot me> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |i at maskray dot me --- Comment #14 from Fangrui Song <i at maskray dot me> --- I agree with Jakub and Andrew. The relevant rules: C11 6.3.2.3 says > An integer may be converted to any pointer type. Except as previously > specified, the result is implementation-defined, might not be correctly > aligned, might not point to an entity of the referenced type, and might be a > trap representation. > > A pointer to an object type may be converted to a pointer to a different > object type. If the resulting pointer is not correctly aligned for the > referenced type, the behavior is undefined. ... C++ [expr.static.cast]p14 says of conversions from a misaligned pointer: > A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type > “pointer to cv2 T”, where T is an object type and cv2 is the same > cv-qualification as, or greater cv-qualification than, cv1. If the original > pointer value represents the address A of a byte in memory and A does not > satisfy the alignment requirement of T, then the resulting pointer value is > unspecified. ... Which is allowed to be an invalid pointer value, which the compiler is then permitted to give whatever semantics we like, such as disallowing it being passed to memcpy. --- memcpy is preferred for expressing an unaligned access. typedef struct dir_entry dir_entry_u __attribute__((aligned(1))); // In C++, there is an alternative: using dir_entry_u __attribute__((aligned(1))) = dir_entry; u64 gu(dir_entry_u *entry) { return entry->offset; }