Created on 2016-05-08.00:00:00 last changed 89 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
,pop
ordisable_recursion_pending
on 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 |