Title
Too strong precondition on basic_string constructor
Status
resolved
Section
[string.cons]
Submitter
Andrzej Krzemienski

Created on 2018-05-09.00:00:00 last changed 65 months ago

Messages

Date: 2018-08-15.14:27:58

Proposed resolution:

This wording is relative to N4750.

  1. Edit [string.cons] as indicated:

    basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
    

    -12- Requires: [s, s + n) is a valid ranges points to an array of at least n elements of charT.

    -13- Effects: Constructs an object of class basic_string and determines its initial string value from the range [s, s + n)array of charT of length n whose first element is designated by s.

    -14- Postconditions: data() points at the first element of an allocated copy of the array whose first element is pointed at by s, size() is equal to n, and capacity() is a value at least as large as size(), and traits::compare(data(), s, n) == 0.

Date: 2018-11-25.18:34:32

[ 2018-08 mailing list discussion ]

This will be resolved by Tim's string rework paper.

Resolved by the adoption of P1148 in San Diego.

Date: 2018-06-18.00:00:00

[ 2018-06-18 after reflector discussion ]

Priority set to 2

Date: 2016-06-04.00:00:00

[ 2016-06-04 Marshall provides alternate resolution ]

Date: 2018-06-04.18:54:45

The following is the spec for basic_string constructor taking a pointer and a size in N4741 ([string.cons]/12-14):

basic_string(const charT* s, size_type n, const Allocator& a = Allocator());

(12) Requires: s points to an array of at least n elements of charT.

(13) Effects: Constructs an object of class basic_string and determines its initial string value from the array of charT of length n whose first element is designated by s.

(14) Postconditions: data() points at the first element of an allocated copy of the array whose first element is pointed at by s, size() is equal to n, and capacity() is a value at least as large as size().

This implies that passing a null pointer and a zero size to this constructor is violating the precondition, as null pointer cannot be described as "pointing to an array of at least n elements of charT". On the other hand, being able to pass {nullptr, 0} is essential for basic_string to be able to inter-operate with other containers that are allowed to use the null pointer value to represent sequences of size zero:

std::vector<char> v{};
assert(v.data() == nullptr); // on some implementations
std::string s(v.data(), v.size()); // nullptr on some implementations

This has been already acknowledged as a defect in issue 2235 and applied, but the resolution still implies a too strong precondition.

Previous resolution [SUPERSEDED]:

This wording is relative to N4741.

  1. Edit [string.cons] as indicated:

    basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
    

    -12- Requires: Unless n == 0, s points to an array of at least n elements of charT.

    -13- Effects: Constructs an object of class basic_string and, unless n == 0, determines its initial string value from the array of charT of length n whose first element is designated by s.

    -14- Postconditions: If n != 0, then data() points at the first element of an allocated copy of the array whose first element is pointed at by s,; size() is equal to n, and capacity() is a value at least as large as size().

History
Date User Action Args
2018-11-25 18:34:32adminsetstatus: open -> resolved
2018-08-15 14:27:58adminsetmessages: + msg10073
2018-06-19 05:49:11adminsetmessages: + msg9949
2018-06-04 18:54:45adminsetmessages: + msg9862
2018-06-04 18:54:45adminsetstatus: new -> open
2018-05-10 18:07:56adminsetmessages: + msg9848
2018-05-09 00:00:00admincreate