868. Default construction and value-initialization

Section: 26 [containers] Status: C++11 Submitter: Alberto Ganesh Barbati Opened: 2008-07-22 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [containers].

View all other issues in [containers].

View all issues with C++11 status.

Discussion:

The term "default constructed" is often used in wording that predates the introduction of the concept of value-initialization. In a few such places the concept of value-initialization is more correct than the current wording (for example when the type involved can be a built-in) so a replacement is in order. Two of such places are already covered by issue 867. This issue deliberately addresses the hopefully non-controversial changes in the attempt of being approved more quickly. A few other occurrences (for example in std::tuple, std::reverse_iterator and std::move_iterator) are left to separate issues. For std::reverse_iterator, see also issue 408. This issue is related with issue 724.

[ San Francisco: ]

The list provided in the proposed resolution is not complete. James Dennett will review the library and provide a complete list and will double-check the vocabulary.

This issue relates to Issue 886 tuple construction

[ 2009-07 Frankfurt ]

The proposed resolution is incomplete.

Move to Tentatively NAD Future. Howard will contact Ganesh for wording. If wording is forthcoming, Howard will move it back to Review.

[ 2009-07-18 Ganesh updated the proposed wording. ]

Howard: Moved back to Review. Note that 20.5.3.1 [utility.arg.requirements] refers to a section that is not in the current working paper, but does refer to a section that we expect to reappear after the de-concepts merge. This was a point of confusion we did not recognize when we reviewed this issue in Frankfurt.

Howard: Ganesh also includes a survey of places in the WP surveyed for changes of this nature and purposefully not treated:

Places where changes are not being proposed

In the following paragraphs, we are not proposing changes because it's not clear whether we actually prefer value-initialization over default-initialization (now partially covered by 1012):

In the following paragraphs, the expression "default constructed" need not be changed, because the relevant type does not depend on a template parameter and has a user-provided constructor:

[ 2009-08-18 Daniel adds: ]

I have no objections against the currently suggested changes, but I also cross-checked with the list regarding intentionally excluded changes, and from this I miss the discussion of

  1. 24.3.2.1 [string.require] p. 2:

    "[..] The Allocator object used shall be a copy of the Allocator> object passed to the basic_string object's constructor or, if the constructor does not take an Allocator argument, a copy of a default-constructed Allocator object."

  2. N2723, 29.6.1.4 [rand.req.eng], Table 109, expression "T()":

    Pre-/post-condition: "Creates an engine with the same initial state as all other default-constructed engines of type X."

    as well as in 29.6.5 [rand.predef]/1-9 (N2914), 29.6.7.1 [rand.util.seedseq]/3, 30.7.4.1.1 [istream.cons]/3, 30.7.5.1.1 [ostream.cons]/9 (N2914), 31.13 [re.grammar]/2, 33.3.2.4 [thread.thread.assign]/1 (N2914),

    [ Candidates for the "the expression "default constructed" need not be changed" list ]

    I'm fine, if these would be added to the intentionally exclusion list, but mentioning them makes it easier for other potential reviewers to decide on the relevance or not-relevance of them for this issue.

  3. I suggest to remove the reference of [func.referenceclosure.invoke] in the "it's not clear" list, because this component does no longer exist.

  4. I also suggest to add a short comment that all paragraphs in the resolution whether they refer to N2723 or to N2914 numbering, because e.g. "Change 26.3.8.2 [deque.cons] para 5" is an N2723 coordinate, while "Change 26.3.8.3 [deque.capacity] para 1" is an N2914 coordinate. Even better would be to use one default document for the numbering (probably N2914) and mention special cases (e.g. "Change 20.5.3.1 [utility.arg.requirements] para 2" as referring to N2723 numbering).

[ 2009-08-18 Alisdair adds: ]

I strongly believe the term "default constructed" should not appear in the library clauses unless we very clearly define a meaning for it, and I am not sure what that would be.

In those cases where we do not want to replace "default constructed" with "vale initialized" we should be using "default initialized". If we have a term that could mean either, we reduce portability of programs.

I have not done an exhaustive review to clarify if that is a vendor freedom we have reason to support (e.g. value-init in debug, default-init in release) so I may yet be convinced that LWG has reason to define this new term of art, but generally C++ initialization is confusing enough without supporting further ill-defined terms.

[ 2009-10 Santa Cruz: ]

Move to Ready.

[ 2010 Pittsburgh: ]

Moved to review in order to enable conflict resolution with 704.

[ 2010-03-26 Daniel harmonized the wording with the upcoming FCD. ]

[ 2010 Rapperswil: ]

Move to Ready.

[ Adopted at 2010-11 Batavia ]

Proposed resolution:

Change 20.5.3.1 [utility.arg.requirements] para 2:

2 In general, a default constructor is not required. Certain container class member function signatures specify the default constructorT() as a default argument. T() shall be a well-defined expression (8.5) if one of those signatures is called using the default argument (8.3.6).

Change 26.3.8.2 [deque.cons] para 3:

3 Effects: Constructs a deque with n default constructedvalue-initialized elements.

Change 26.3.8.3 [deque.capacity] para 1:

1 Effects: If sz < size(), equivalent to erase(begin() + sz, end());. If size() < sz, appends sz - size() default constructedvalue-initialized elements to the sequence.

Change 26.3.9.2 [forwardlist.cons] para 3:

3 Effects: Constructs a forward_list object with n default constructedvalue-initialized elements.

Change 26.3.9.5 [forwardlist.modifiers] para 22:

22 Effects: [...] For the first signature the inserted elements are default constructedvalue-initialized, and for the second signature they are copies of c.

Change 26.3.10.2 [list.cons] para 3:

3 Effects: Constructs a list with n default constructedvalue-initialized elements.

Change 26.3.10.3 [list.capacity] para 1:

1 Effects: If sz < size(), equivalent to list<T>::iterator it = begin(); advance(it, sz); erase(it, end());. If size() < sz, appends sz - size() default constructedvalue-initialized elements to the sequence.

Change 26.3.11.2 [vector.cons] para 3:

3 Effects: Constructs a vector with n default constructedvalue-initialized elements.

Change 26.3.11.3 [vector.capacity] para 9:

9 Effects: If sz < size(), equivalent to erase(begin() + sz, end());. If size() < sz, appends sz - size() default constructedvalue-initialized elements to the sequence.