According to [basic.align]
Object types have alignment requirements ([basic.fundamental], [basic.compound]) which place restrictions on the addresses at which an object of that type may be allocated.
I would expect a C++ compiler is allowed to assume that any pointer to T points to a correctly aligned T.
e.g. (if alignof(int) == 4)
int* p = /* ... */
auto val = p[0];
if ((reinterpret_cast<std::uintptr_t>(p) & 3) != 0) {
// assumed to be unreachable
}
However, testing GCC and clang in compiler explorer, I don't see either of them making this assumption. Even if I dereference the pointer (which surely would cause UB if it was not correctly aligned) this pointer-value assumption is not made.
I recognise that the mapping of pointers to integer values is implementation defined, and that perhaps the compiler has a mapping other than what this code assumes (though, I don't think so).
I also recognise that there may be a lot of code in production would break by making this assumption, explaining why it's not currently done by these compilers.
My question is: According to the standard, would it be a valid assumption a compiler could make?
If not, please cite the standard!
EDIT: clarified that the pointer is dereferenced.
EDIT2: say alignof() (instead of sizeof())
Yes compilers may assume the pointer is properly aligned.
Let us assume for the time being there's a function is_aligned which tests whether the address pointed to by a pointer has proper alignment for its type.
int* p = /* ... */
auto val = p[0];
if (is_aligned(p)) {
// assumed to be unreachable
}
Will then be true. We deduce this from [basic.life]
The lifetime of an object of type
Tbegins when:
- storage with the proper alignment and size for type
Tis obtained [...]
Thus no object that has improper alignment exists. It then follows that the pointer is either a null pointer, invalid or pointing to an object of another type.
Accessing through a null pointer is illegal, access through invalid pointers is also illegal, and so is access to an object of another type†, which makes access through misaligned pointers UB.
† with exception of unsigned char, char and std::byte
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With