27

I've searched through the standard about unaligned access, but didn't find anything (maybe I was inadvertent).

Is it undefined behavior? Is it implementation defined?

As a lot of current CPUs support unaligned access, it would be sensible that unaligned memory access is implementation defined. Is it the case?

By unaligned access, I mean for example:

alignas(int) char buffer[sizeof(int)+1];
int &x = *new(buffer+1) int;
x = 42;
curiousguy
  • 8,038
  • 2
  • 40
  • 58
geza
  • 28,403
  • 6
  • 61
  • 135
  • 1
    I think the relevant section is **[basic.align]**. Implementation-defined. – Raymond Chen Jul 01 '18 at 19:26
  • 1
    @RaymondChen: all I found is that alignment value is implementation defined. But nothing about unaligned access. Do you see something else there? – geza Jul 01 '18 at 19:35
  • How do we know that this is an unaligned access? `sizeof(int)` and the required alignment are both implementation defined. Could be the same as for `char`. – Bo Persson Jul 01 '18 at 21:13

1 Answers1

24

No, it is UB. You cannot start the lifetime of an object at unaligned memory. From [basic.life]p1

The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and

  • if the object has non-vacuous initialization, its initialization is complete,

[...]

So in your example, the lifetime of the object referenced by x doesn't even begin, so any other usage of it other than mentioned in [basic.life]p6 is UB.

But what your implementation is allowed to do is say that unaligned memory (as specified by the underlying architecture used) is actually aligned, thus making your code valid under the C++ abstract machine. I'm not sure whether any compiler does this however.

Community
  • 1
  • 1
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • The alignment requirement is, however, an implementation defined property. – Maxim Egorushkin Jul 01 '18 at 19:48
  • 1
    @MaximEgorushkin: that's true, but does it matter? Suppose that the requirement is 4. Does my example's behaviour implementation defined, or UB? Reading the quoted part, I think that Rakete1111 is right, and it is UB indeed, because `new int` is called on an unaligned pointer. – geza Jul 01 '18 at 19:58
  • @MaximEgorushkin Yes it is implementation defined. But that doesn't change the fact that if that requirement is violated, no matter what it is, then you get UB, which is AFAIK exactly what OP does by adding 1. – Rakete1111 Jul 01 '18 at 20:01
  • @geza Suppose the implementation has best performance if 4-byte integers are alinged by 4-byte boundary. But it can handle unaligned access just fine. What should `alignof(uint32_t)` return? – Maxim Egorushkin Jul 01 '18 at 20:08
  • 2
    @MaximEgorushkin Whatever compiler developers decide it should return. It could return `1`, or it could (as on my GCC) return `4`. If hardware allows misaligned access with a performance overhead, the implementation can still return `4` to make (most) integers aligned, improving performance. – HolyBlackCat Jul 01 '18 at 20:10
  • @HolyBlackCat You don't have to develop a compiler to return that `1`. Just a back-end https://llvm.org/docs/WritingAnLLVMBackend.html – Maxim Egorushkin Jul 01 '18 at 20:13
  • 1
    @MaximEgorushkin Here by compiler I mean an entire tool that makes object files from C++ source code. – HolyBlackCat Jul 01 '18 at 20:15
  • 1
    You only need to provide a definition of _proper alignment_ now. – Maxim Egorushkin Jul 01 '18 at 20:15
  • 2
    @MaximEgorushkin It's probably the alignment that `alignof` returns. – HolyBlackCat Jul 01 '18 at 20:16
  • 1
    @HolyBlackCat Quote the standard please. – Maxim Egorushkin Jul 01 '18 at 20:17
  • 1
    @MaximEgorushkin Are you trying to say that there is a possibility that `alignof` returns optimal rather than required alignment? The standard doesn't mention 'proper alignment' anywhere else, the closest thing I was able to find is [`[basic.align]/2`](http://eel.is/c++draft/basic.align#2) *"The result of the alignof operator reflects the alignment requirement ..."*. – HolyBlackCat Jul 01 '18 at 20:36
  • @Rakete1111 Actually, [basic.align]/2 has an interesting part in it: *"The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. ... The result of the alignof operator reflects the alignment requirement of the type in the complete-object case."* So one could say that you're allowed to access misaligned compound types under certain conditions. – HolyBlackCat Jul 01 '18 at 20:42
  • @HolyBlackCat: in the case of x86, it certainly returns optimal alignment, as there is no required alignment on x86 (except a few special cases). Almost all variables could use an alignment of 1, and even, there would be no significant speed loss. – geza Jul 02 '18 at 06:28
  • 1
    @HolyBlackCat: but according to the standard, alignof means required alignment (3.11.6 of C++14). So, implementations with `alignof(int)==4` give us a more strict alignment than necessary. – geza Jul 02 '18 at 06:44
  • @geza At the risk of stating the obvious, an implementation is free to impose a stricter alignment requirement than the underlying hardware. Also, hardware-unaligned access has obvious issues with `volatile` semantics on x86 (apart from "real" hardware access, this is very relevant for [`sig_atomic_t`](https://en.cppreference.com/w/c/program/sig_atomic_t)). – Arne Vogel Jul 02 '18 at 11:03
  • @ArneVogel: the question is then, is a memory access is UB, when the memory access is aligned from the perspective of the HW, but unaligned from the perspective of the C++ abstract machine? It seems that the answer is yes, but it is not 100% explicit in the standard. – geza Jul 02 '18 at 11:23
  • 2
    @geza It is explicit. The abstract machine doesn't care about alignement of the underlying HW. If the compiler says that the memory is unaligned, then you get UB no matter the HW. – Rakete1111 Jul 02 '18 at 11:27
  • 1
    @Rakete1111: my only problem is that it says "proper alignment", not "required aligment" (which equals to `alignof`). Not a big deal, I agree with your conclusion, all I'm saying is that sentence can be improved a little bit – geza Jul 02 '18 at 11:29
  • 2
    @geza I understand proper as "right", which is what alignof returns. It could be improved, I agree. – Rakete1111 Jul 02 '18 at 11:31