'What is the reason for std::memcpy not being constexpr even in C++20?
I understand that copying arbitrary chunks of memory is not always possible to do at compile time but since we are getting constexpr constainers, virtual methods and also algorithms, why not memcpy too? It is too a kind of algorithm.
Furthemore,
- C++20
std::bit_castseems a lot likestd::memcpyworkaroundreinterpret_castbut it isconstexpr. std::copyusing iterators is marked asconstexprfor C++20, so copying is somehow possible for types.
The usage would be to either copy or just "reinterpret" variables/arrays in constexpr functions, the former is not solved by std::bit_cast AFAIK. In particular, the question and my answer would like to use it.
- Is there any particular reason for why
std::bit_castcan be constexpr butstd::memcpycannot? - Does it have to do with memcpy using void pointers instead of typed references?
- Not actually having to copy anything?
- C backwards compatibility?
- Maybe because there is no support for a "pointer to constexpr memory"? But the same applies to the reference parameter in
std::bit_castand iterators instd::copy.
Relevant answer to C++20 bit_cast vs reinterpret_cast briefly cites from somewhere:
Furthermore, it is currently impossible to implement a constexpr bit-cast function, as memcpy itself isn’t constexpr. Marking the proposed function as constexpr doesn’t require or prevent memcpy from becoming constexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has a bitcast opcode).
But it does not go into detail of not making it constexpr too.
Note, that I do not ask for why std::bit_cast exists. I like it, it provides a clear intention instead of std::memcpy workaround.
Solution 1:[1]
That's more a comment then an answer as I'm only citing what is written in P0202R0: Add Constexpr Modifiers to Functions in and Headers, but I write it here as is does not fit the comments:
B.
std::memmoveandstd::memcpymust have constexpr additionsstd::memmoveandstd::memcpyacceptvoid*andconst void*parameters. This makes them impossible to implement in pure C++ asconstexpr, because constant expressions can not evaluate a conversion from typecv void *to a pointer-to-object type according to [expr.const].
However those functions are not only popular, but also are widely used across Standard Library to gain better performance. Not making them constexpr will force standard Library developer to have compiler intrinsics for them anyway. This is a hard step that must be done.
The related section of [expr.const]:
8.6 Constant expressions [expr.const]
[…]An expressioneis a core constant expression unless the evaluation ofe, following the rules of the abstract machine (6.8.1), would evaluate one of the following expressions:
[…]
(2.13) — a conversion from typecv void*to a pointer-to-object type;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | t.niese |
