2659. [filesys.ts] [PDTS] Invalid expressions for bitmask types

Section: 10 [filesys.ts::fs.enum] Status: NAD Editorial Submitter: Daniel Krügler Opened: 2014-03-01 Last modified: 2016-08-11 20:23:09 UTC

Priority: Not Prioritized

View all issues with NAD Editorial status.


Addresses: filesys.ts

copy_options is declared as enum class type that is a bismask type, but the specification repeatedly uses expressions that are invalid for scoped enums, such as:


because there is no contextual conversion to bool, not even the || operator in:

((options & copy_options::recursive) || !(options))

Affected are basically all formulations in the form:

"if options & copy_options::create_symlinks [..]"

because all rely on contextual conversion to bool. The only other specifically mention scoped enumeration in the standard that is also a bit mask type is the launch enum and the wording there always uses forms such as:

"if policy & launch::deferred is non-zero"

which better acknowledges the fact that the obtained values does not necessarily undergo an implicit conversion.

I think the current wording in the file system spec. must be changed, especially for invalid expressions of the form:

((options & copy_options::recursive) || !(options))

A similar problem arises in the usage of the bitmask type perms for the expression:

((prms & add_perms) && (prms & remove_perms))

The only way how to describe this with a scoped enum is the lengthier form

((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) != perms::none)

thus fixing several problems:

[20 May 2014 Beman Dawes provides proposed wording. Fixing invalid C++ is editorial, but treating this as an issue ensures more people review the proposed changes.]

[17 Jun 2014 Rapperswil LWG requests issue be handled as editorial.]

Proposed resolution:

Change 15.3 Copy [fs.op.copy]:

Before the first use of f and t:

Report an error as specified in Error reporting (7) if:

If is_symlink(f), then:

Otherwise if is_regular_file(f), then:

Otherwise if is_directory(f) && ((options & copy_options::recursive) != copy_options::none || !(options == copy_options::none)) then:

Change 15.4 Copy file [fs.op.copy_file]:

If  exists(to) && !(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none report a file already exists error as specified in Error reporting (7).

If !exists(to) || (options & copy_options::overwrite_existing) != copy_options::none || ((options & copy_options::update_existing) != copy_options::none && last_write_time(from) > last_write_time(to)) || !(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none copy the contents and attributes of the file from resolves to the file to resolves to.

Change 15.26 Permissions [fs.op.permissions]:

Requires: !((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) != perms::none).