Revised 2013-01-15 at 16:01:04 UTC
Section: 30.6.8 [futures.async] Status: Tentatively NAD Editorial Submitter: Nicolai Josuttis Opened: 2011-08-29 Last modified: 2012-11-14
View other active issues in [futures.async].
View all other issues in [futures.async].
View all issues with Tentatively NAD Editorial status.
Discussion:
The current throw specification of async() does state:
-6- Throws: system_error if policy is launch::async and the implementation is unable to start a new thread.
First it seems not clear whether this only applies if policy equals launch::async of if the async launch mode flag is set (if policy|launch::async!=0)
In the discussion Lawrence Crowl also wrote:More generally, I think what we want to say is that if the implementation cannot successfully execute on one of the policies allowed, then it must choose another. The principle would apply to implementation-defined policies as well.
Peter Sommerlad:
Should not throw. That was the intent. "is async" meat exactly.
[2012, Portland: move to Tentatively NAD Editorial]
If no launch policy, it is undefined behavior.
Agree with Lawrence, should try all the allowed policies. We will rephrase so that the policy argument should be lauch::async. Current wording seems good enough.
We believe this choice of policy statement is really an editorial issue.
Proposed resolution:
Section: 30.4.4 [thread.once] Status: Tentatively Ready Submitter: Nicolai Josuttis Opened: 2011-08-30 Last modified: 2012-11-14
View all issues with Tentatively Ready status.
Discussion:
In function call_once 30.4.4.2 [thread.once.callonce] paragraph 4 and 5 specify for call_once():
Throws: system_error when an exception is required (30.2.2 [thread.req.exception]), or any exception thrown by func.
Error conditions:
- invalid_argument — if the once_flag object is no longer valid.
However, nowhere in 30.4.4 [thread.once] is specified, when a once-flag becomes invalid.
As far as I know this happens if the flag is used for different functions. So we either have to have to insert a sentence/paragraph in30.4.4.2 Function call_once [thread.once.callonce]
or
30.4.4 Call once [thread.once]
explaining when a once_flag becomes invalidated or we should state as error condition something like:
Anthony Williams:
A once_flag is invalidated if you destroy it (e.g. it is an automatic object, or heap allocated and deleted, etc.)
If the library can detect that this is the case then it will throw this exception. If it cannot detect such a case then it will never be thrown.
Jonathan Wakely:
I have also wondered how that error can happen in C++, where the type system will reject a non-callable type being passed to call_once() and should prevent a once_flag being used after its destructor runs.
If a once_flag is used after its destructor runs then it is indeed undefined behaviour, so implementations are already free to throw any exception (or set fire to a printer) without the standard saying so. My assumption was that it's an artefact of basing the API on pthreads, which says:The pthread_once() function may fail if:
[EINVAL] If either once_control or init_routine is invalid.
Pete Becker:
Yes, probably. We had to clean up several UNIXisms that were in the original design.
[2012, Kona]
Remove error conditions, move to Review.
[2012, Portland: move to Tentatively Ready]
Concurrency move to Ready, pending LWG review.
LWG did not have time to perform the final review in Portland, so moving to tentatively ready to reflect the Concurrency belief that the issue is ready, but could use a final inspection from library wordsmiths.
Proposed resolution:
This wording is relative to N3337.
Change 30.4.4.2 [thread.once.callonce] as indicated:
template<class Callable, class ...Args> void call_once(once_flag& flag, Callable&& func, Args&&... args);[…]
-4- Throws: system_error when an exception is required (30.2.2), or any exception thrown by func.-5- Error conditions:
invalid_argument — if the once_flag object is no longer valid.
Section: 19.5.5 [syserr.hash], 20.7.2.6 [util.smartptr.hash], 20.8.12 [unord.hash], 20.13.1 [type.index.synopsis], 21.6 [basic.string.hash], 23.3.7 [vector.bool], 30.3.1.1 [thread.thread.id] Status: Tentatively Ready Submitter: Daniel Krügler Opened: 2011-12-04 Last modified: 2012-11-14
View all issues with Tentatively Ready status.
Discussion:
20.7.2.6 [util.smartptr.hash] p2 is specified as follows:
Requires: the template specializations shall meet the requirements of class template hash (20.8.12).
The problem here is the usage of a Requires element, which is actually a pre-condition that a user of a component has to satisfy. But the intent of this wording is actually to be a requirement on implementations. The Requires element should be removed here and the wording should be improved to say what it was intended for.
We have similar situations in basically all other places where the specification of library-provided hash specializations is defined. Usually, the Requires element is incorrect. In the special case of hash<unique_ptr<T, D>> the implementation depends on the behaviour of hash specializations, that could be user-provided. In this case the specification needs to separate the requirements on these specializations and those that are imposed on the implementation.[2012, Kona]
Update wording and move to Review.
Believe a simpler formulation is to simply string the term Requires: and leave the current wording intact, rather than strike the whole clause and replace it.
[Originally proposed wording for reference
Change 19.5.5 [syserr.hash] as indicated:
-1- Change 20.5.3 [bitset.hash] as indicated:
-1- Change 20.7.2.6 [util.smartptr.hash] as indicated:
-1-
template <> struct hash<error_code>;
Requires: the template specialization shall meet the requirements
of class template hash (20.8.12 [unord.hash])The header
<system_error> provides a definition for a specialization of the
template hash<error_code>. The requirements for the members of
this specialization are given in sub-clause 20.8.12 [unord.hash].
template <size_t N> struct hash<bitset<N> >;
Requires: the template specialization shall meet the requirements
of class template hash (20.8.12 [unord.hash])The header
<bitset> provides a definition for a partial specialization of the
hash class template for specializations of class template bitset<N>.
The requirements for the members of instantiations of this specialization are given
in sub-clause 20.8.12 [unord.hash].
template <class T, class D> struct hash<unique_ptr<T, D> >;
Requires: the template specialization shall meet the requirements
of class template hash (20.8.12 [unord.hash])The header
<memory> provides a definition for a partial specialization of the
hash class template for specializations of class template unique_ptr<T, D>.
The requirements for the members of instantiations of this specialization are given
in sub-clause 20.8.12 [unord.hash]. For an object p of type
UP, where UP is unique_ptr<T, D>,
hash<UP>()(p) shall evaluate to the same value as
hash<typename UP::pointer>()(p.get()). The specialization
hash<typename UP::pointer> shall be well-formed.
template <class T> struct hash<shared_ptr<T> >;-2-
Requires: the template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <memory> provides a definition for a partial specialization of the hash class template for specializations of class template shared_ptr<T>. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object p of type shared_ptr<T>, hash<shared_ptr<T> >()(p) shall evaluate to the same value as hash<T*>()(p.get()).
Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]
template <> struct hash<bool>; template <> struct hash<char>; […] template <> struct hash<long double>; template <class T> struct hash<T*>;-2-
Requires: the template specializations shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <functional> provides definitions for specializations of the hash class template for each cv-unqualified arithmetic type except for the extended integer types. This header also provides a definition for a partial specialization of the hash class template for any pointer type. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].
Change 20.13.4 [type.index.hash] p1 as indicated:
template <> struct hash<type_index>;-1-
Requires: the template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <typeindex> provides a definition for a specialization of the template hash<type_index>. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object index of type type_index, hash<type_index>()(index) shall evaluate to the same result as index.hash_code().
Change 21.6 [basic.string.hash] p1 as indicated:
template <> struct hash<string>; template <> struct hash<u16string>; template <> struct hash<u32string>; template <> struct hash<wstring>;-1-
Requires: the template specializations shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <string> provides definitions for specializations of the hash class template for the types string, u16string, u32string, and wstring. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].
Change 23.3.7 [vector.bool] p7 as indicated:
template <class Allocator> struct hash<vector<bool, Allocator> >;-7-
Requires: the template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <vector> provides a definition for a partial specialization of the hash class template for specializations of class template vector<bool, Allocator>. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash].
Change 30.3.1.1 [thread.thread.id] p14 as indicated:
template <> struct hash<thread::id>;-14-
Requires: the template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash])The header <thread> provides a definition for a specialization of the template hash<thread::id>. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash].
[2012, Portland: Move to Tentatively Ready]
No further wording issues, so move to Tentatively Ready (post meeting issues processing).
Proposed resolution:
Change 19.5.5 [syserr.hash] as indicated:
template <> struct hash<error_code>;-1-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash].
Change 20.5.3 [bitset.hash] as indicated:
template <size_t N> struct hash<bitset<N> >;-1-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]).
Change 20.7.2.6 [util.smartptr.hash] as indicated:
template <class T, class D> struct hash<unique_ptr<T, D> >;-1-
-?- Requires: The specialization hash<typename UP::pointer> shall be well-formed and well-defined, and shall meet the requirements of class template hash (20.8.12 [unord.hash]).Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]). For an object p of type UP, where UP is unique_ptr<T, D>, hash<UP>()(p) shall evaluate to the same value as hash<typename UP::pointer>()(p.get()).The specialization hash<typename UP::pointer> shall be well-formed.
template <class T> struct hash<shared_ptr<T> >;-2-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]). For an object p of type shared_ptr<T>, hash<shared_ptr<T> >()(p) shall evaluate to the same value as hash<T*>()(p.get()).
Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]
template <> struct hash<bool>; template <> struct hash<char>; […] template <> struct hash<long double>; template <class T> struct hash<T*>;-2-
Requires: tThe template specializations shall meet the requirements of class template hash (20.8.12 [unord.hash]).
Change 20.13.4 [type.index.hash] p1 as indicated:
template <> struct hash<type_index>;-1-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]). For an object index of type type_index, hash<type_index>()(index) shall evaluate to the same result as index.hash_code().
Change 21.6 [basic.string.hash] p1 as indicated:
template <> struct hash<string>; template <> struct hash<u16string>; template <> struct hash<u32string>; template <> struct hash<wstring>;-1-
Requires: tThe template specializations shall meet the requirements of class template hash (20.8.12 [unord.hash]).
Change 23.3.7 [vector.bool] p7 as indicated:
template <class Allocator> struct hash<vector<bool, Allocator> >;-7-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]).
Change 30.3.1.1 [thread.thread.id] p14 as indicated:
template <> struct hash<thread::id>;-14-
Requires: tThe template specialization shall meet the requirements of class template hash (20.8.12 [unord.hash]).
Section: 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class] Status: Tentatively NAD Editorial Submitter: Vicente J. Botet Escriba Opened: 2012-01-01 Last modified: 2012-11-14
View other active issues in [thread.timedmutex.requirements].
View all other issues in [thread.timedmutex.requirements].
View all issues with Tentatively NAD Editorial status.
Discussion:
30.4.1.3.1 [thread.timedmutex.class] says:
The class timed_mutex shall satisfy all of the TimedMutex requirements (30.4.1.3 [thread.timedmutex.requirements]). It shall be a standardlayout class (Clause 9 [class]).
Problem here is that 30.4.1.3 [thread.timedmutex.requirements] does not define a requirement set named "TimedMutex", it only refers to "timed mutex types"
[See also issue 2126]
[2012, Portland: move to Tentatively NAD Editorial]
We have timed mutex type, but it is labeled timed mutex requirements
We can make a suggestion, but will send to the editor as it seems purely editorial. There is a typo, and we don't have the timed mutex but 30.4.1.3 [thread.timedmutex.requirements] already says timed mutex type, and we need to reuse that term down in the class to fulfil the mutex requirement.
[To Editor:]
Replace this one with timed mutex type.
Proposed resolution:
Section: 30.4.1 [thread.mutex.requirements], 30.4.1.2.1 [thread.mutex.class], 30.4.1.2 [thread.mutex.requirements.mutex], 30.4.1.2.2 [thread.mutex.recursive], 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class], 30.4.1.3.2 [thread.timedmutex.recursive] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-01-16 Last modified: 2012-11-14
View all other issues in [thread.mutex.requirements].
View all issues with Tentatively NAD Editorial status.
Discussion:
30.4.1.2.1 [thread.mutex.class]/3 says that the class mutex "shall satisfy all the Mutex requirements (30.4.1 [thread.mutex.requirements])". 30.4.1.2.1 [thread.mutex.class] is part of 30.4.1 [thread.mutex.requirements], so at the very least, this requirement is recursive. But worse, there is nothing that says what "the Mutex requirements" refers to. For example, the "Lockable requirements" section starts with "A type L meets the Lockable requirements if …". There is no such statement for "the Mutex requirements".
Organizationally, paragraphs 1-26 in 30.4.1.2 [thread.mutex.requirements.mutex] should probably be in a subclause with a name. (This is actually an ISO requirement, to avoid exactly this kind of ambiguous referencing) Then the first sentence of 30.4.1.2.1 [thread.mutex.class]/3 can become a note: "The class mutex meets the requirements of (whatever)", since that subclause already says that the mutex types "shall meet the requirements set out in this section." And similarly for 30.4.1.2.2 [thread.mutex.recursive]/2 (recursive_mutex). 30.4.1.3 [thread.timedmutex.requirements], Timed mutex types, also needs the same rearrangement: its introductory requirements should be moved into a subclause, and the first sentences of 30.4.1.3.1 [thread.timedmutex.class]/2 and 30.4.1.3.2 [thread.timedmutex.recursive]/2 should be turned into notes that refer to this new subclause and to the new subclause in 30.4.1.2 [thread.mutex.requirements.mutex].[See also issue 2125]
[2012, Portland: move to Tentatively NAD Editorial]
Seems no real ambiguity. May need some reorg of text rather then changing the wording.
Is there much that needs to be changed? But Pete's suggestion of putting requirement in separate sub section is good. Should be the direction to editor.
Suggest this is an editorial change. Happy with Pete's comments.
Proposed resolution:
Section: 30.4.1.2 [thread.mutex.requirements.mutex] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-03-05 Last modified: 2012-11-14
View all other issues in [thread.mutex.requirements.mutex].
View all issues with Tentatively NAD Editorial status.
Discussion:
30.4.1.2 [thread.mutex.requirements.mutex]/11 says that prior unlock operations synchronize with m.lock().
30.4.1.2 [thread.mutex.requirements.mutex]/19 says that if m.try_lock() succeeds, prior unlock operations synchronize with the operation. 30.4.1.2 [thread.mutex.requirements.mutex]/25 says that m.unlock() synchronizes with subsequent successful lock operations. Does the third requirement add anything to the first two? If not, it should probably be a non-normative note.[2012, Portland: move to Tentatively NAD Editorial]
Agree that third note should be non-normative and adds nothing.
Seems An Editorial change, but does changing a normative to non-normative wording makes it a non-editorial change?
Ask the editor. If not editorial, then we will agree on the fix as removal of the third point, then we will put it in ready state for Bristol.
Proposed resolution:
Section: 23.2.1 [container.requirements.general] Status: Tentatively NAD Submitter: Dean Michael Berris Opened: 2012-07-13 Last modified: 2012-11-14
View other active issues in [container.requirements.general].
View all other issues in [container.requirements.general].
Discussion:
Table 96 defines the general requirement for copy assignment (row 23, page 704) as:
Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity |
---|---|---|---|---|
r = a | X& | post: r == a. | linear |
However there is no requirement that T is CopyInsertable into X.
[2012, Portland: Move to Tentatively NAD]
Howard notes that this may be a difficult requirement for std::array
We already have this requirement for allocator aware containers, and std::array already adds the appropriate extra requirement.
We say the necessary things in the necessary places, but the container requirements continue to cause confusion in where we sometimes say things. Consensus is that this issue remains NAD though.
Proposed resolution:
This wording is relative to N3376.
Change Table 96 — "Container requirements" in 23.2.1 [container.requirements.general]:
Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity |
---|---|---|---|---|
r = a | X& |
Requires: T is CopyInsertable into X. post: r == a. |
linear |
Section: 23.2.1 [container.requirements.general] Status: Tentatively Ready Submitter: Loïc Joly Opened: 2012-08-10 Last modified: 2012-11-14
View other active issues in [container.requirements.general].
View all other issues in [container.requirements.general].
View all issues with Tentatively Ready status.
Discussion:
See also discussion following c++std-lib-32883 and c++std-lib-32897.
The requirements on CopyInsertable and MoveInsertable are either incomplete, or complete but hard to figure out. From e-mail c++std-lib-32897: Pablo Halpern: I agree that we need semantic requirements for all of the *Insertable concepts analogous to the requirements we have on similar concepts. Howard Hinnant: I've come to believe that the standard is actually correct as written in this area. But it is really hard to read. I would have no objection whatsoever to clarifications to CopyInsertable as you suggest (such as the post-conditions on v). And I do agree with you that the correct approach to the clarifications is to confirm that CopyInsertable implies MoveInsertable.[2012, Portland: Move to Tentatively Ready]
Move to Tentatively Ready by unanimous consent.
Proposed resolution:
This wording is relative to N3376.
Edit 23.2.1 [container.requirements.general] p13 as indicated:
-13- […] Given a container type X having an allocator_type identical to A and a value_type identical to T and given an lvalue m of type A, a pointer p of type T*, an expression v of type (possibly const) T, and an rvalue rv of type T, the following terms are defined. If X is not allocator-aware, the terms below are defined as if A were std::allocator<T> — no allocator object needs to be created and user specializations of std::allocator<T> are not instantiated:
T is DefaultInsertable into X means that the following expression is well-formed:
allocator_traits<A>::construct(m, p);An element of X is default-inserted if it is initialized by evaluation of the expression
allocator_traits<A>::construct(m, p);where p is the address of the uninitialized storage for the element allocated within X.
T is
CopyMoveInsertable into X means that the following expression is well-formed:allocator_traits<A>::construct(m, p, rv);and when evaluated the following postconditions hold: The value of *p is equivalent to the value of rv before the evaluation. [Note: rv remains a valid object. Its state is unspecified — end note]
T is
MoveCopyInsertable into X means that, in addition to satisfying the MoveInsertable requirements, the following expression is well-formed:allocator_traits<A>::construct(m, p,rv);and when evaluated the following postconditions hold: The value of v is unchanged and is equivalent to *p.
T is EmplaceConstructible into X from args, for zero or more arguments args, means that the following expression is well-formed:
allocator_traits<A>::construct(m, p, args);T is Erasable from X means that the following expression is well-formed:
allocator_traits<A>::destroy(m, p);[Note: A container calls allocator_traits<A>::construct(m, p, args) to construct an element at p using args. The default construct in std::allocator will call ::new((void*)p) T(args), but specialized allocators may choose a different definition. — end note]
Section: 23.3.7 [vector.bool] Status: Tentatively Ready Submitter: Nevin Liber Opened: 2012-09-21 Last modified: 2012-11-14
View all other issues in [vector.bool].
View all issues with Tentatively Ready status.
Discussion:
It should have them so that it more closely matches the vector<T> interface, as this helps when writing generic code.
[2012, Portland: Move to Tentatively Ready]
Question on whether the variadic template is really needed, but it turns out to be needed to support emplace of no arguments.
Proposed resolution:
This wording is relative to N3376.
Change the class template vector<bool> synopsis, 23.3.7 [vector.bool] p1, as indicated:
namespace std { template <class Allocator> class vector<bool, Allocator> { public: […] // modifiers: template <class... Args> void emplace_back(Args&&... args); void push_back(const bool& x); void pop_back(); template <class... Args> iterator emplace(const_iterator position, Args&&... args); iterator insert(const_iterator position, const bool& x); […] }; }