[recursive_]directory_iterator
constructors refer to undefined options
Section: 31.12.11.2 [fs.dir.itr.members], 31.12.12.2 [fs.rec.dir.itr.members] Status: New Submitter: Jonathan Wakely Opened: 2022-01-31 Last modified: 2024-01-29
Priority: 3
View all other issues in [fs.dir.itr.members].
View all issues with New status.
Discussion:
31.12.11.2 [fs.dir.itr.members] p2 and 31.12.12.2 [fs.rec.dir.itr.members] p3 refer to the options
parameter, but not all overloads have a parameter of that name.
[2022-03-04; Reflector poll]
Set priority to 3 after reflector poll.
[2022-12-18; Daniel comments and provides wording]
It seems to me that we should differentiate the problems of directory_iterator
and
recursive_directory_iterator
regarding the constructors that don't provide any options
arguments
at least from a logical point of view:
recursive_directory_iterator
we can at least
guess that the intention of the existing wording is that these suppose to reflect that the effective options within
the Effects: element are also equal to directory_options::none
.
But for directory_iterator
we don't have any options "getter" nor Postconditions from deducing
the intent.
Fortunately, existing implementations (I looked at the current V2 2022 library and libstdc++ implementation)
seem to behave already as if directory_options::none
is set for the affected constructors for both
iterator types.
Note that this issue here has some wording overlap with the the proposed wording of LWG 2708,
I'm therefore using the exact wording form currently suggested there. If LWG would like to change this form (e.g.
by using the word "overload" instead of "signature") this should also be done in that other issue to reduce possible
merge conflicts. Note that the here suggested form using "signature" has existing practice in other places
of Clause 31.12 [filesystems], so I recommend keeping that form.
Proposed resolution:
This wording is relative to N4917.
Modify 31.12.11.2 [fs.dir.itr.members] as indicated:
[Drafting note:
(1) The proposed wording form takes care to use the same wording form used in LWG 2708 forrecursive_directory_iterator
at the time of writing.
(2) We don't need similar wording for the default constructor because this creates an end iterator and there exist no way for the user to observe the effects ofdirectory_options
for such an iterator value. ]
directory_iterator() noexcept;-1- Effects: Constructs the end iterator.
explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec); directory_iterator(const path& p, directory_options options, error_code& ec);-?- For the signatures with no parameter
-2- Effects: For the directory thatoptions
, letoptions
bedirectory_options::none
.p
resolves to, constructs an iterator for the first element in a sequence ofdirectory_entry
elements representing the files in the directory, if any; otherwise the end iterator. However, if(options & directory_options::skip_permission_denied) != directory_options::noneand construction encounters an error indicating that permission to access
[…]p
is denied, constructs the end iterator and does not report an error.
Modify 31.12.12.2 [fs.rec.dir.itr.members] as indicated:
[Drafting note:
(1) The proposed wording form takes care to be in sync with the wording form used in LWG 2708 at the time of writing. This issue here doesn't touch the wording for theoptions
function though, and leaves any changes to LWG 2708, because these changes don't seem essential to solve the issue here.
(2) We don't need similar wording for the default constructor because this creates an end iterator and from 31.12.12.1 [fs.class.rec.dir.itr.general] p2 we can conclude that user code has no way to determine the effectivedirectory_options
value of this iterator value (interestingly p15 quoted below can be read to apply here as well, but 31.12.12.1 [fs.class.rec.dir.itr.general] p2 seems to be very prohibitive and LWG 2708 is going to solve this special case as well).
(3) We easily simplify the wording of p3 as shown below, because the "scope" of the introductory new paragraph includes the Postconditions: element. But similar to the arguments provided in (1) we don't wish to introduce merge conflicts with the LWG 2708 wording and therefore intentionally leave any changes of p3 to that issue. ]
recursive_directory_iterator() noexcept;-1- Effects: Constructs the end iterator.
explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec); recursive_directory_iterator(const path& p, error_code& ec);[…]-?- For the signatures with no parameter
-2- Effects: Constructs an iterator representing the first entry in the directory to whichoptions
, letoptions
bedirectory_options::none
.p
resolves, if any; otherwise, the end iterator. However, if(options & directory_options::skip_permission_denied) != directory_options::noneand construction encounters an error indicating that permission to access
-3- Postconditions:p
is denied, constructs the end iterator and does not report an error.options() == options
for the signatures with adirectory_options
argument, otherwiseoptions() == directory_options::none
. […]directory_options options() const;-15- Returns: The value of the argument passed to the constructor for the
-16- Throws: Nothing.options
parameter, if present, otherwisedirectory_options::none
.