https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114217
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- GCC actually doesn't diagnose on mere pointer assignment, but what triggers the alignment check is &entry->offset even when the code later on just takes its address, entry must be sufficiently aligned, otherwise entry->offset is invalid. Under standard C rules, already forming the pointer would be UB, so somewhere in the caller when you prepare what to pass to the f function. If you want something that will still be invalid C, but will not trigger UBSAN errors, then e.g. unsigned long long h(struct dir_entry *entry) { return get_unaligned((unsigned long long *) (((char *) entry) + offsetof (struct dir_entry, offset))); } will do. If you want something that will be valid even in C, don't pass struct dir_entry *entry argument, but void *entry instead, and use e.g. __get_unaligned_t(__typeof(((struct dir_entry *)0)->offset), ((char *)entry)+offsetof(struct dir_entry, offset))) You can surely hide that all under some macro.