Reputation: 16834
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.)
Upvotes: 28
Views: 3208
Reputation: 21
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)
Upvotes: 1
Reputation: 97
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.
Upvotes: 1