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.
std::basic_string's data() and operator[] specificationSection: 27.4.3.6 [string.access] Status: New Submitter: Peter Bindels Opened: 2025-09-16 Last modified: 2025-10-21
Priority: 4
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)ifpos < size(). Otherwise, returns a reference to an object of typecharTwith valuecharT(), where modifying the object to any value other thancharT()leads to undefined behavior.
The specification for data() in 27.4.3.8.1 [string.accessors] p1 (and p4) says, however:
Returns: A pointer
psuch thatp + i == addressof(operator[](i))for eachiin[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.
operator[] to
Returns:
*(begin() + pos)ifpos <= size(). The program shall not modify the value stored atsize()to any value other thancharT(); 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.
[2025-10-21; Reflector poll.]
Set priority to 4 after reflector poll.
"NAD. begin() + size() is not dereferenceable and should remain that way."
"Saying "if pos <= size() is redundant given the precondition above."
"The resolution removes any guarantee that the value at str[str.size()]
is charT(). Furthermore, the premise of the issue is incorrect,
returning the address of a different null terminator not belonging to the
string would make traversing it with other string operations UB, so it
has to return a reference to a terminator that's within the same array."
"*(begin() = size()) is UB, but could use *(data() + size()) instead.
Personally I'd like *end() to be valid, but that's certainly LEWG business
requiring a paper."
Proposed resolution:
This wording is relative to N5014.
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:
-2- Returns:pos <= size()istrue.*(begin() + pos)ifpos <= size().Otherwise, returns a reference to an object of type-3- Throws: Nothing. -4- Complexity: Constant time. -?- Remarks The program shall not modify the value stored atcharTwith valuecharT(), where modifying the object to any value other thancharT()leads to undefined behavior.size()to any value other thancharT(); otherwise, the behavior is undefined