2232. [CD] The char_traits specializations should declare their length(), compare(), and find() members constexpr

Section: 24.2.3 [char.traits.specializations] Status: Resolved Submitter: Jeffrey Yasskin Opened: 2012-12-24 Last modified: 2017-06-10

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.

  1. In 24.2.3.1 [char.traits.specializations.char], 24.2.3.2 [char.traits.specializations.char16_t], 24.2.3.3 [char.traits.specializations.char32_t], and 24.2.3.4 [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);