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
.
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.
Alternative A (remove the noexcept
):
Edit [fs.class.directory_iterator], class directory_iterator
synopsis, as indicated:
directory_iterator& operator++(); directory_iterator& increment(error_code& ec)noexcept;
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.
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;
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.
Alternative B (specify that increment
reports an error if the iterator is not dereferenceable):
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
-11- Returns:increment
reports an error if*this
is not dereferenceable.*this
. -12- Throws: As specified in 27.10.7.
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:
-25- Throws: As specified in 27.10.7.*this
.