The Standard Library provides a great collection of containers and algorithms, many of which currently lack constexpr support.
Even a simple constexpr
usage requires reimplementing a big bunch of the Standard Library. Consider the simple example:
#include <array> #include <cstring> template <std::size_t N> constexpr auto copy_some(const char* begin) { std::array<char, N> result = {}; // ERROR: non-constexpr function 'memcpy' cannot be used in a constant expression std::memcpy(result.begin(), begin, N); return result; } int main () { constexpr char a[] = { 'H', 'e', 'l', 'l', 'o' }; constexpr auto res = copy_some<sizeof(a)>(a); }
This proposal concentrates on simplification of constexpr
algorithms development, deferring the constexpr
modifications of the standard headers to a separate proposals.
This proposal is a core extension. It proposes no changes to existing headers. The changes do not break existing code and do not degrade performance.
void*
to pointers to char
, unsigned char
Existing implementations of the functions in <algorithm>
header usually rely on functions from <cstring>
.
For example std::copy
usually takes advantage of std::memmove
for POD types. This makes the memory copying functions
widely used all around the Standard Library.
Many of the memory copying functions accept parameters by pointers to void
. This proposal relaxes only those conversions that do not
affect aliasing, because some of the existing compilers rely heavily on aliasing rules.
reinterpret_cast
ing pointers to pointers to char
, unsigned char
This is a generalization of a previous bulletin. Having the ability to cast to void
pointers and from void
pointers to single byte types
it is possible to implement reinterpret_cast
from scratch, so there's no reason for keeping the reinterpret_cast
restriction any more.
reinterpret_cast
restrictions N4567 contains restrictions on constant expressions, that make any UB code not a constant expression: [expr.const] "(2.5) — an operation that would have
undefined behavior as specified in Clauses 1 through 16". So any attempt to make reinterpret_cast
that results in UB will make the expression non-constant.
N4567 describes all the conversions from a function pointer to an object pointer type or vice versa as conditionally-supported, so there's no need to describe that restriction in [expr.const]: it's up to the compiler vendors to allow or disallow such conversions.
All the additions to the Standard are marked with underlined green.
(2.11) — a conversion from type cv void * to a pointer-to-object type, other than cv char* or cv unsigned char*; (2.12) — a dynamic cast (5.2.7); (2.13) — a reinterpret_cast, other than a cast from cv pointer type to cv char* or cv unsigned char* (5.2.10);
For the purposes of SG10, we recommend the feature-testing macro name __cpp_constexpr_to_char_casts
.
Revision 1:
[N4567] Working Draft, Standard for Programming Language C++. Available online at www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf
[Discussion] A call to discuss asm in constexpr and constexpr <algorithm>. Available online at https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/9sTJWsOpptE
Walter E. Brown provided numerous comments, corrections, and suggestions for this proposal.