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

### 2840. `directory_iterator::increment` is seemingly narrow-contract but marked `noexcept`

Section: 31.12.11.2 [fs.dir.itr.members], 31.12.12.2 [fs.rec.dir.itr.members] Status: Resolved Submitter: Tim Song Opened: 2016-12-09 Last modified: 2020-09-06

Priority: 2

View all other issues in [fs.dir.itr.members].

View all issues with Resolved status.

Discussion:

`directory_iterator::increment` and `recursive_directory_iterator::increment` are specified by reference to the input iterator requirements, which is narrow-contract: it has a precondition that the iterator is dereferenceable. Yet they are marked as `noexcept`.

Either the `noexcept` (one of which was added by LWG 2637) should be removed, or the behavior of `increment` when given a nondereferenceable iterator should be specified.

Currently, libstdc++ and MSVC report an error via the `error_code` argument for a nondereferenceable `directory_iterator`, while libc++ and `boost::filesystem` assert.

[2017-01-27 Telecon]

Priority 2; there are some problems with the wording in alternative B.

[2018-01-24 Tim Song comments]

LWG 3013 will remove this `noexcept` (for a different reason). The behavior of calling `increment` on a nondereferenceble iterator should still be clarified, as I was informed that LWG wanted it to be well-defined.

[2018-1-26 issues processing telecon]

Part A is already done by 3013.

Marshall to talk to Tim about Part B; it would be odd if `operator++` was undefined behaviour, but `increment` on the same iterator returned an error

[2018-8-15 Offline discussions]

Tim and Marshall recommend NAD for about Part B

[2018-08-20 Batavia Issues processing]

Status to resolved.

Proposed resolution:

This wording is relative to N4618.

1. Alternative A (remove the `noexcept`):

   1. Edit 99 [fs.class.directory_iterator], class `directory_iterator` synopsis, as indicated:

      >     directory_iterator& operator++();
      >     directory_iterator& increment(error_code& ec) noexcept;

   2. Edit 31.12.11.2 [fs.dir.itr.members] before p10 as indicated:

      >     directory_iterator& operator++();
      >     directory_iterator& increment(error_code& ec) noexcept;

      > > -10- Effects: As specified for the prefix increment operation of Input iterators (24.2.3).

      > > -11- Returns: `*this`.

      > > -12- Throws: As specified in 27.10.7.

   3. Edit 31.12.12 [fs.class.rec.dir.itr], class `recursive_directory_iterator` synopsis, as indicated:

      >     recursive_directory_iterator& operator++();
      >     recursive_directory_iterator& increment(error_code& ec) noexcept;

   4. Edit 31.12.12.2 [fs.rec.dir.itr.members] before p23 as indicated:

      >     recursive_directory_iterator& operator++();
      >     recursive_directory_iterator& increment(error_code& ec) noexcept;

      > > -23- Effects: As specified for the prefix increment operation of Input iterators (24.2.3), except that: […]

      > > -24- Returns: `*this`.

      > > -25- Throws: As specified in 27.10.7.

2. Alternative B (specify that `increment` reports an error if the iterator is not dereferenceable):

   1. Edit 31.12.11.2 [fs.dir.itr.members] p10 as indicated:

      >     directory_iterator& operator++();
      >     directory_iterator& increment(error_code& ec) noexcept;

      > > -10- Effects: As specified for the prefix increment operation of Input iterators (24.2.3), except that `increment` reports an error if `*this` is not dereferenceable.

      > > -11- Returns: `*this`.

      > > -12- Throws: As specified in 27.10.7.

   2. Edit 31.12.12.2 [fs.rec.dir.itr.members] p23 as indicated:

      >     recursive_directory_iterator& operator++();
      >     recursive_directory_iterator& increment(error_code& ec) noexcept;

      > > -23- Effects: As specified for the prefix increment operation of Input iterators (24.2.3), except that:

      > > - `increment` reports an error if `*this` is not dereferenceable.

      > > - If there are no more entries at the current depth, […]

      > > - Otherwise if […]

      > > -24- Returns: `*this`.

      > > -25- Throws: As specified in 27.10.7.