char_traits
specializations should declare their length()
, compare()
, and
find()
members constexprSection: 27.2.4 [char.traits.specializations] Status: Resolved Submitter: Jeffrey Yasskin Opened: 2012-12-24 Last modified: 2020-09-06
Priority: Not Prioritized
View all other issues in [char.traits.specializations].
View all issues with Resolved status.
Discussion:
Addresses ES 14, US 19
These functions have easy recursive constexpr implementations that, unfortunately, aren't efficient at runtime. EWG is still figuring out how to solve this problem in general (e.g., N3444 isn't sufficient to avoid stack overflows in debug builds or to get the optimal assembly-based implementations at runtime), so users can't portably solve this problem for themselves, but implementations can use compiler-specific techniques to choose the right implementation inside their standard libraries.
The LWG is still undecided about whether individual implementations can add constexpr to these functions, so we
need to add constexpr
to the standard here for implementations to be able to improve this.
[2013-03-15 Issues Teleconference]
Moved to Open.
There are a number of people who have a strong interest in this issue not available for the telecon.
It also plays at the heart of a discussion about library freedoms for constexpr
and specifying
a library that may depend on unspecified compiler intrinsics to be implementable.
[2013-09 Chicago]
Moved to NAD Future.
While it is clear that this feature can be implemented using only C++14 constexpr
features,
there is real concern that we cannot call the efficient, highly optimized, C implementations of these
functions under a C++14 constexpr
implementation, nor implement similar ourselves as this
typically involves use of inline asm
instructions.
Clang and libc++ have some experience of using intrinsics to try to address the performance issue, but
the current intrinsics are not general enough to support char_traits
. The intrinsics support
only operations on character string literals, and the string literal is no longer visible as a
literal after passing as a const char *
to the char_traits
functions.
Additional concern was raised that these operations are unlikely to be useful anyway, as the only client
is basic_string
which relies on dynamic memory allocation, and so cannot effectively be made a
literal type. Jeffrey then pointed out the pending string_view
library that will also use
char_traits
and would most certainly benefit from being a literal type.
Given the choice of giving up performance on a critical library component, or requiring a compiler intrinsic with only unsuccessful implementation experience, the consensus is to not reject this, unless compelling implementation experience is demonstrated. NAD Future seems the appropriate resolution.
[2017-06-02 Issues Telecon]
Resolved by P0426R1, adopted in Issaquah.
Proposed resolution:
This wording is relative to N3691.
In 27.2.4.2 [char.traits.specializations.char], [char.traits.specializations.char16_t], [char.traits.specializations.char32_t], and 27.2.4.6 [char.traits.specializations.wchar.t]:
static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a);