This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4378. Inconsistency between std::basic_string's data() and operator[] specification

Section: 27.4.3.6 [string.access] Status: New Submitter: Peter Bindels Opened: 2025-09-16 Last modified: 2025-09-21

Priority: Not Prioritized

View all other issues in [string.access].

View all issues with New status.

Discussion:

From the working draft N5014, the specification for operator[] in 27.4.3.6 [string.access] p2 says:

Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.

The specification for data() in 27.4.3.8.1 [string.accessors] p1 (and p4) says, however:

Returns: A pointer p such that p + i == addressof(operator[](i)) for each i in [0, size()].

The former implies that str[str.size()] is allowed to be the address of any null terminator, while the latter restricts it to only being the null terminator belonging to the string.

Suggested fix: Change wording around operator[] to

Returns: *(begin() + pos) if pos <= size(). The program shall not modify the value stored at size() to any value other than charT(); otherwise, the behavior is undefined.

This moves it inline with the data() specification. Given the hardened precondition that pos <= size() this does not change behavior for any in-contract access, and we do not define what the feature does when called with broken preconditions. I have been looking at the latter but that will be an EWG paper instead.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 27.4.3.6 [string.access] as indicated:

    constexpr const_reference operator[](size_type pos) const;
    constexpr       reference operator[](size_type pos);
    

    -1- Hardened preconditions: pos <= size() is true.

    -2- Returns: *(begin() + pos) if pos <= size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.

    -3- Throws: Nothing.

    -4- Complexity: Constant time.

    -?- Remarks The program shall not modify the value stored at size() to any value other than charT(); otherwise, the behavior is undefined