Constexpr placement new?
Asked Answered
O

2

27

The C++ standard specifically bans calling new in a constant expression (N4296 section 5.20 [expr.const]):

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

...

— a new-expression (5.3.4);

This ban (as far as I can see) extends to all forms of new, including placement new. However, since placement new doesn't actually allocate any memory and merely runs constructors at the given location, and since it's legal to take the address of a variable in a constexpr context (indeed, std::addressof will be constexpr in C++17), it seems to me that this prohibition could (in principle at least) be eased to allow placement new in constexpr functions.

So my question is, am I missing something? Is there a good reason why placement new is forbidden in constexpr functions?

(For context: the current rules pretty much require that constexpr-enabled sum types like std::variant are implemented as a recursive union. It would be nicer to be able to use something like std::aligned_storage and placement new, but currently that's not possible.)

Operate answered 10/1, 2017 at 23:5 Comment(3)
"It would be nicer to be able to use something like std::aligned_storage and placement new" I don't think so, and given that reinterpret_cast is banned in constant expression, I don't think you can implement std::variant in this way even with constexpr placement new.Newspaper
groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/…Brice
@Brice You should really summarize that discussion as an answer.Rafaelita
F
1

There's no conceptual reason that placement new couldn't work. I suppose this was an oversight, placement new is basically just a call to the constructor in a predefined memory location.

Ensuring the placement new parameter has a valid argument location isn't any harder than ensuring a write to random pointer is valid.

Fid answered 25/4, 2018 at 17:46 Comment(1)
one of reason that such things would not work is presence of canadian crosses and simply cross-compilers. It becomes night-impossible to deduce behaviour with thoseColy
S
1

Placement new do not mix well with the curent constexpr world, because it allows to build an object with its underlying byte representation (with value-initialization). And this is not defined in the standard (two-complement is not even in constexpr, as reminder)

Looking at C++ standard discussions, it could alternatively allow to peek into the object type representation afterwards (as you still hold the byte array)

Soundproof answered 18/4, 2020 at 14:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.