Title
recursive_directory_iterator's members should require '*this is dereferenceable'
Status
c++17
Section
[fs.rec.dir.itr.members][fs.dir.itr.members]
Submitter
Eric Fiselier

Created on 2016-05-08.00:00:00 last changed 81 months ago

Messages

Date: 2017-03-19.19:35:20

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.]

  1. 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.

  2. Add a new bullet after the class synopsis in [fs.class.rec.dir.itr]:

    -?- Calling options, depth, recursion_pending, pop or disable_recursion_pending on an iterator that is not dereferencable results in undefined behavior.
  3. 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().

    […]

Date: 2016-06-27.16:44:20

[ 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

Date: 2017-03-19.19:35:20

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:43adminsetstatus: wp -> c++17
2016-06-28 12:55:35adminsetstatus: immediate -> wp
2016-06-27 16:44:20adminsetstatus: new -> immediate
2016-06-20 20:55:11adminsetmessages: + msg8184
2016-05-08 18:31:51adminsetmessages: + msg8106
2016-05-08 00:00:00admincreate