Created on 2016-05-08.00:00:00 last changed 100 months ago
Proposed resolution:
This wording is relative to N4582.
[Drafting note: I have not attempted to fix the specification of the copy/move constructors and assignment operators for recursive_directory_iterator]
[Drafting note: increment directly specifies "Effects: As specified by Input iterators (24.2.3)", so no additional specification is needed.]
Change [fs.class.directory_iterator] p4 as indicated:
-4-
The result of operator* on an end iterator is undefined behavior. For any other iterator value a const directory_entry& is returned. The result of operator-> on an end iterator is undefined behavior. For any other iterator value a const directory_entry* is returnedThe end iterator is not dereferenceable.
Add a new bullet after the class synopsis in [fs.class.rec.dir.itr]:
-?- Callingoptions,depth,recursion_pending,popordisable_recursion_pendingon an iterator that is not dereferencable results in undefined behavior.
Change [fs.rec.dir.itr.members] as indicated:
directory_options options() const;-17-
[…]Requires: *this != recursive_directory_iterator().int depth() const;-20-
[…]Requires: *this != recursive_directory_iterator().bool recursion_pending() const;-23-
[…]Requires: *this != recursive_directory_iterator().recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec) noexcept;-26-
[…]Requires: *this != recursive_directory_iterator().void pop();-30-
[…]Requires: *this != recursive_directory_iterator().void disable_recursion_pending();-32-
[…]Requires: *this != recursive_directory_iterator().
[ 2016-06, Oulu — Daniel comments ]
The loss of information caused by bullet three of the suggested wording below is corrected by 2726's wording.
Voted to Ready 7-0 Monday morning in Oulu
In [fs.rec.dir.itr.members] the following members are specified as having the requirement "*this != recursive_directory_iterator{}":
options()
depth()
recursion_pending()
operator++
increment(...)
pop()
disable_recursion_pending()
This requirement is not strong enough since it still allows non-dereferenceable iterators to invoke these methods. For example:
recursive_directory_iterator it(".");
recursive_directory_iterator it_copy(it);
assert(it_copy.depth() == 0); // OK
++it;
assert(it_copy.depth() == ???); // Not OK
auto x = *it_copy; // Is this OK?
I believe these should instead require that *this is dereferenceable, however the current specification seems to say that all previous copies of it are still dereferenceable although not what they dereference to.
[fs.class.directory_iterator] p4:The result of operator* on an end iterator is undefined behavior. For any other iterator value a const recursive_directory_entry& is returned. The result of operator-> on an end iterator is undefined behavior. For any other iterator value a const directory_entry* is returned.
Is the intention of this clause to make all non-end iterators dereferenceable?
One further complication with these methods comes from the specification of recursive_directory_iterator's copy/move constructors and assignment operators which specify the following post conditions:this->options() == rhs.options()
this->depth() == rhs.depth()
this->recursion_pending() == rhs.recursion_pending()
If rhs is the end iterator these post conditions are poorly stated.
| History | |||
|---|---|---|---|
| Date | User | Action | Args | 
| 2017-07-30 20:15:43 | admin | set | status: wp -> c++17 | 
| 2016-06-28 12:55:35 | admin | set | status: immediate -> wp | 
| 2016-06-27 16:44:20 | admin | set | status: new -> immediate | 
| 2016-06-20 20:55:11 | admin | set | messages: + msg8184 | 
| 2016-05-08 18:31:51 | admin | set | messages: + msg8106 | 
| 2016-05-08 00:00:00 | admin | create | |