Is placement new legally required for putting an i

2019-03-09 11:30发布

There seems to be some agreement that you can't willy nilly point (an int*) into a char array because of the C++ aliasing rules.

From this other question -- Generic char[] based storage and avoiding strict-aliasing related UB -- it seems that it is allowed to (re-)use storage through placement new.

alignas(int) char buf[sizeof(int)];

void f() {
  // turn the memory into an int: (??) from the POV of the abstract machine!
  ::new (buf) int; // is this strictly required? (aside: it's obviously a no-op)

  // access storage:
  *((int*)buf) = 42; // for this discussion, just assume the cast itself yields the correct pointer value
}

So, is the above legal C++ and is the placement new actually needed to make it legal?

2条回答
虎瘦雄心在
2楼-- · 2019-03-09 11:43

Yes, the placement new is necessary, otherwise you'd violate strict aliasing (assignment is access).

Is the above legal? Almost (although it will work on virtually all implementations). The pointer you've created through the cast does not point to the object, because the (now destroyed) array and the int object are not pointer-interconvertible; use std::launder((int*)buf), or better yet, use the placement new's return value.

查看更多
放荡不羁爱自由
3楼-- · 2019-03-09 11:57
*((int*)buf) = 42;

writes an int with a int lvalue, so there is no aliasing issue in the first place.

查看更多
登录 后发表回答