4 ms·
We need an '__unaligned' modifier for pointers to specify that the pointer will be used for unaligned reads and writes.
by Dwedit 3y ago
We need an '__unaligned' modifier for pointers to specify that the pointer will be used for unaligned reads and writes.
- Athas 3y agoWhy not just use memcpy()?
- greesil 3y agoArrays?
- j16sdiz 3y agoBecause, in some hardware, unaligned read is ok. and you want to take advantage of the hardware feature?
- dzaima 3y agoBoth gcc and clang will optimize a memcpy to an unaligned load/store where possible.
- j16sdiz 3y agoIf the compiler is so smart, I guess it could insert a memcpy when needed? The standard, you may say.. I would argue it's the standard need to be changed. The modern reading of the standard is not useful as a low-level language and is unsafe as a high-level language.
- dzaima 3y agoRight, I agree that it would be nice to have some way to request unaligned load/store to be permitted, alike -fwrapv for signed int wrapping. But nevertheless the UB behavior is a reasonable option that's beneficial for other things.
- rsaxvc 3y ago> If the compiler is so smart, I guess it could insert a memcpy when needed? If I'm reading your comment and the blog post correctly, the compiler would need a memory like access on every multibyte pointer argument where the compiler cannot otherwise prove alignment. Is that correct?
- rsaxvc 3y ago> memory like I meant memcpy()-like
- dzaima 3y agoInternally, the compiler could represent it however it wants. LLVM IR's load/store instructions just have an "align" property, which is usually sizeof(the type), but can be set to 1 to mimic memcpy (and indeed llvm/clang immediately translate a memcpy to such - https://godbolt.org/z/7T46a6aqT https://godbolt.org/z/7T46a6aqT). Though it seems that, independent of this, it assumes that an int* in general will be 4-byte-aligned, so e.g. https://godbolt.org/z/aWTEd4s3K https://godbolt.org/z/aWTEd4s3K still has an "align 4" despite using memcpy. So one must also cast to a char* before using memcpy() to actually have it work. yay for more footguns!
- IshKebab 3y agoThat is the solution they recommend.
- mtklein 3y agoIf you've got control over the type of the pointee and not just the pointer, __attribute__((packed)) can work for this. struct foo { int x; }; struct bar { __attribute__((packed)) int x; }; _Static_assert(_Alignof(struct foo) == 4, ""); _Static_assert(_Alignof(struct bar) == 1, "");
- loeg 3y agoYeah, I end up using __attribute__((packed)) for this at work. For tortured reasons, part of our codebase allocates memory with only 8-byte alignment, but the buffer is cast to a type that would have 16-byte alignment without __attribute__((packed)). As a result Clang wants to generate VMOVDQAs that require 16-byte alignment, unless you use packed, in which case it generates VMOVDQU.