Revised 2016-07-11 at 06:07:25 UTC
Section: 23.2 [container.requirements] Status: Tentatively NAD Submitter: Paolo Carlini Opened: 2007-11-11 Last modified: 2016-02-12
Priority: 2
View other active issues in [container.requirements].
View all other issues in [container.requirements].
View all issues with Tentatively NAD status.
Discussion:
In an emplace member function the function parameter pack may be bound to a priori unlimited number of objects: some or all of them can be elements of the container itself. Apparently, in order to conform to the blanket statement 23.2 [container.requirements]/11, the implementation must check all of them for that possibility. A possible solution can involve extending the exception in 23.2 [container.requirements]/12 also to the emplace member. As a side note, the push_back and push_front member functions are luckily not affected by this problem, can be efficiently implemented anyway.
[ Related to 767 and to 2164 ]
[ Bellevue: ]
The proposed addition (13) is partially redundant with the existing paragraph 12. Why was the qualifier "rvalues" added to paragraph 12? Why does it not cover subelements and pointers?
Resolution: Alan Talbot to rework language, then set state to Review.
[ 2009-07 Frankfurt ]
The problem is broader than emplace. The LWG doesn't feel that it knows how to write wording that prohibits all of the problematic use cases at this time.
NAD Future.
[2015-02 Cologne]
LWG believes that 2164 addresses this issue and therefore considers 760 as NAD.
Proposed resolution:
Add after 23.2 [container.requirements]/12:
-12- Objects passed to member functions of a container as rvalue references shall not be elements of that container. No diagnostic required.
-13- Objects bound to the function parameter pack of the emplace member function shall not be elements or sub-objects of elements of the container. No diagnostic required.
Section: 20.11.2.5 [util.smartptr.enab], 20.11.2.2.1 [util.smartptr.shared.const] Status: Tentatively Resolved Submitter: Daniel Krügler Opened: 2012-08-16 Last modified: 2016-05-17
Priority: 3
View other active issues in [util.smartptr.enab].
View all other issues in [util.smartptr.enab].
View all issues with Tentatively Resolved status.
Discussion:
On reflector message c++std-lib-32927, Matt Austern asked whether the following example should be well-defined or not
struct X : public enable_shared_from_this<X> { }; auto xraw = new X; shared_ptr<X> xp1(xraw); shared_ptr<X> xp2(xraw);
pointing out that 20.11.2.2.1 [util.smartptr.shared.const] does not seem to allow it, since xp1 and xp2 aren't allowed to share ownership, because each of them is required to have use_count() == 1. Despite this wording it might be reasonable (and technical possible) to implement that request.
On the other hand, there is the non-normative note in 20.11.2.5 [util.smartptr.enab] p11 (already part of TR1):The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member.
Now according to the specification in 20.11.2.2.1 [util.smartptr.shared.const] p3-7:
template<class Y> explicit shared_ptr(Y* p);
the notion of creating unique pointers can be read to be included by this note, because the post-condition of this constructor is unique() == true. Evidence for this interpretation seems to be weak, though.
Howard Hinnant presented the counter argument, that actually the following is an "anti-idiom" and it seems questionable to teach it to be well-defined in any case:auto xraw = new X; shared_ptr<X> xp1(xraw); shared_ptr<X> xp2(xraw);
He also pointed out that the current post-conditions of the affected shared_ptr constructor would need to be reworded.
It needs to be decided, which direction to follow. If this idiom seems too much broken to be supported, the note could be improved. If it should be supported, the constructors in 20.11.2.2.1 [util.smartptr.shared.const] need a careful analysis to ensure that post-conditions are correct. Several library implementations currently do not support this example, instead they typically cause a crash. Matt points out that there are currently no explicit requirements imposed on shared_ptr objects to prevent them from owning the same underlying object without sharing the ownership. It might be useful to add such a requirement.[2013-03-15 Issues Teleconference]
Moved to Open.
More discussion is needed to pick a direction to guide a proposed resolution.
[2013-05-09 Jonathan comments]
The note says the newly created shared_ptr is assigned to the weak_ptr member. It doesn't say before doing that the shared_ptr should check if the weak_ptr is non-empty and possibly share ownership with some other pre-existing shared_ptr.
[2015-08-26 Daniel comments]
LWG issue 2529 is independent but related to this issue.
[2016-03-16, Alisdair comments]
This issues should be closed as Resolved by paper p0033r1 at Jacksonville.
Proposed resolution:
Section: 24.5.1 [reverse.iterators] Status: Tentatively Resolved Submitter: Jeffrey Yasskin Opened: 2012-10-30 Last modified: 2016-05-17
Priority: 3
View all other issues in [reverse.iterators].
View all issues with Tentatively Resolved status.
Discussion:
std::reverse_iterator::reverse_iterator(Iterator) should be constexpr so that other constexpr functions can return reverse_iterators. Of the other methods, the other constructors, base(), operator+, operator-, operator[], and the non-member operators can probably also be constexpr.
operator* cannot be constexpr because it involves an assignment to a member variable. Discussion starting with c++std-lib-33282 indicated that it would be useful to make reverse_iterator a literal type despite this restriction on its use at compile time.Proposed resolution:
This issue was Resolved by paper P0031R0 adopted at Jacksonville, 2016.Section: 18.10 [support.runtime] Status: Tentatively Resolved Submitter: Richard Smith Opened: 2013-02-14 Last modified: 2016-06-28
Priority: 2
View other active issues in [support.runtime].
View all other issues in [support.runtime].
View all issues with Tentatively Resolved status.
Discussion:
According to 18.10 [support.runtime] p2:
The contents of these headers are the same as the Standard C library headers [..], <stdalign.h>, [..]
Since our base C standard is C99, which doesn't have a <stdalign.h>, the reference to a non-existing C header is irritating (In this context <stdalign.h> doesn't refer to the deprecated C++ header <stdalign.h> described in D.4 [depr.c.headers]).
Furthermore, it would be also important that it doesn not define a macro named alignof, which C11 also defines in this header. Currently we only have the following guarantee as part of 18.10 [support.runtime] p7:The header <cstdalign> and the header <stdalign.h> shall not define a macro named alignas.
It is unclear what the better strategy is: Striking the reference to <stdalign.h> in 18.10 [support.runtime] p2 or upgrading to C11 as new base C standard.
[2014-02-15 Issaquah]
STL: related to earlier issue on C4, 2201, and now we get a C11 header
JY: find _Alignof as keyword C11 FDIS has four defines in stdalign.h
AM: need paper for C11 as base library we should really do that
STL: really need vendor input
STL: don't think we need to do anything right now not P1
AM: any objections to downscale to P2 (no objections)
[2016-03 Jacksonville]
Walter: this is on track to go away if we adopt Clark's paper to rebase to C11
Room: tentatively resolved; revisit after C11 paper: P0063
[2016-03 Oulu]
P0063 was adopted.
Change status to Tentatively Resolved
Proposed resolution:
Section: 20.11.2.2.5 [util.smartptr.shared.obs] Status: Tentatively NAD Submitter: Stephan T. Lavavej Opened: 2013-10-05 Last modified: 2016-02-12
Priority: 2
View all other issues in [util.smartptr.shared.obs].
View all issues with Tentatively NAD status.
Discussion:
20.11.1.2.4 [unique.ptr.single.observers]/3: "pointer operator->() const noexcept; Requires: get() != nullptr."
20.11.2.2.5 [util.smartptr.shared.obs]/2: "T& operator*() const noexcept; Requires: get() != 0." 20.11.2.2.5 [util.smartptr.shared.obs]/5: "T* operator->() const noexcept; Requires: get() != 0." Narrow-contract functions should not be noexcept.[2014-02-15 Issaquah]
Issue is contentious, raise to P2.
[2015-02 Cologne]
AM: This ship has sailed. JM: What's the issue? AM: operator-> has narrow contract and should never have had noexcept. DK: Not quite. We explicitly called out that for shared_ptr this is fine. You said so in your "narrow contract" paper. GR: This would be a fairly major regression in the design of {unique,shared}_ptr over raw pointers; raw pointer dereferencing is noexcept. It's not a performance regression but a usability regression. AM: Do we expect users to query noexpect on dereference expressions? Room: Yes. VV: We don't just expect it, we have seen it. JM: Yes, users may be querying something like noexcept(x->y) and expect to be checking y, but silently end up checking x->.
Close as NAD, with explanation from GR. Previous resolution [SUPERSEDED]:This wording is relative to N3691.
In 20.11.1.2 [unique.ptr.single]/1, class template unique_ptr synopsis for single objects, change as indicated:
pointer operator->() constnoexcept;In 20.11.1.2.4 [unique.ptr.single.observers] change as indicated:
pointer operator->() constnoexcept;-3- Requires: get() != nullptr.
-4- Returns: get(). -?- Throws: Nothing. -5- Note: use typically requires that T be a complete type.In 20.11.2.2 [util.smartptr.shared]/1, class template shared_ptr synopsis, change as indicated:
T& operator*() constnoexcept; T* operator->() constnoexcept;In 20.11.2.2.5 [util.smartptr.shared.obs] change as indicated:
T& operator*() constnoexcept;-2- Requires: get() != 0.
-3- Returns: *get(). -?- Throws: Nothing. -4- Remarks: When T is void, it is unspecified whether this member function is declared. If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.T* operator->() constnoexcept;-5- Requires: get() != 0.
-6- Returns: get(). -?- Throws: Nothing.
[2015-03-03, Geoffrey provides rationale]
Rationale:
It is by design that these members are noexcept, and changing that now would be a substantial regression in functionality. These classes were designed to substitute for plain pointers as transparently as possible, so since those operations are effectively noexcept on plain pointers, they should be noexcept on unique_ptr and shared_ptr as well. This matters in practice because we expect these members to be used fairly often inside the noexcept operator, and such code could be broken by this change. These design considerations override our general policy against noexcept for narrow-contract functions.
It is notable that N3279, which proposed this policy, did not propose striking noexcept from these operations. It's not clear if the omission of operator* and operator-> was an oversight, or an intentional reflection of the above considerations. N3279 was based on N3248 by the same authors, which states that:"Most applications of noexcept for unique_ptr and shared_ptr are on functions with wide contracts. However, there are preconditions on the atomic access functions, so these should lose the specification."
Proposed resolution:
Section: 21.3.1 [basic.string] Status: Tentatively Resolved Submitter: Michael Bradshaw Opened: 2014-05-27 Last modified: 2016-05-22
Priority: 3
View other active issues in [basic.string].
View all other issues in [basic.string].
View all issues with Tentatively Resolved status.
Discussion:
Regarding 21.3.1 [basic.string], std::basic_string<charT>::data() returns a const charT* 21.3.1.7.1 [string.accessors]. While this method is convenient, it doesn't quite match std::array<T>::data() 23.3.7.5 [array.data] or std::vector<T>::data() 23.3.11.4 [vector.data], both of which provide two versions (that return T* or const T*). An additional data() method can be added to std::basic_string that returns a charT* so it can be used in similar situations that std::array and std::vector can be used. Without a non-const data() method, std::basic_string has to be treated specially in code that is otherwise oblivious to the container type being used.
Adding a charT* return type to data() would be equivalent to doing &str[0] or &str.front(). Small discussion on the issue can be found here and in the std-discussion thread (which didn't get too much attention). This requires a small change to std::basic_string's definition in 21.3.1 [basic.string] to add the method to std::basic_string, and another small change in 21.3.1.7.1 [string.accessors] to define the new method.[2015-02 Cologne]
Back to LEWG.
[2016-05-22]
Marshall says: this issue has been resolved by P0272R1.
Proposed resolution:
This wording is relative to N3936.
Change class template basic_string synopsis, 21.3.1 [basic.string], as indicated:
namespace std { template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_string { public: […] // 21.4.7, string operations: const charT* c_str() const noexcept; const charT* data() const noexcept; charT* data() noexcept; allocator_type get_allocator() const noexcept; […] }; }
Add the following sequence of paragraphs following 21.3.1.7.1 [string.accessors] p3, as indicated:
charT* data() noexcept;-?- Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
-?- Complexity: Constant time. -?- Requires: The program shall not alter the value stored at p + size().
Section: 20.11.2.5 [util.smartptr.enab] Status: Tentatively Resolved Submitter: Jonathan Wakely Opened: 2015-08-26 Last modified: 2016-05-17
Priority: 3
View other active issues in [util.smartptr.enab].
View all other issues in [util.smartptr.enab].
View all issues with Tentatively Resolved status.
Discussion:
It is unclear what should happen if a pointer to an object with an enable_shared_from_this base is passed to two different shared_ptr constructors.
#include <memory> using namespace std; int main() { struct X : public enable_shared_from_this<X> { }; auto xraw = new X; shared_ptr<X> xp1(xraw); // #1 { shared_ptr<X> xp2(xraw, [](void*) { }); // #2 } xraw->shared_from_this(); // #3 }
This is similar to LWG 2179, but involves no undefined behaviour due to the no-op deleter, and the question is not whether the second shared_ptr should share ownership with the first, but which shared_ptr shares ownership with the enable_shared_from_this::__weak_this member.
With all three of the major std::shared_ptr implementations the xp2 constructor modifies the __weak_this member so the last line of the program throws bad_weak_ptr, even though all the requirements on the shared_from_this() function are met (20.11.2.5 [util.smartptr.enab])/7:Requires: enable_shared_from_this<T> shall be an accessible base class of T. *this shall be a subobject of an object t of type T. There shall be at least one shared_ptr instance p that owns &t.
Boost doesn't update __weak_this, leaving it sharing with xp1, so the program doesn't throw. That change was made to boost::enable_shared_from_this because someone reported exactly this issue as a bug, see Boost issue 2584.
On the reflector Peter Dimov explained that there are real-world use cases that rely on the Boost behaviour, and none which rely on the behaviour of the current std::shared_ptr implementations. We should specify the behaviour of enable_shared_from_this more precisely, and resolve this issue one way or another.[2016-03-16, Alisdair comments]
This issues should be closed as Resolved by paper p0033r1 at Jacksonville.
Proposed resolution:
Section: 17.5.2.1.3 [bitmask.types] Status: Tentatively NAD Submitter: Hubert Tong Opened: 2016-04-14 Last modified: 2016-05-22
Priority: 3
View all other issues in [bitmask.types].
View all issues with Tentatively NAD status.
Discussion:
The usual pattern now used for identifying where bitmask elements are declared, namely, as variables, preclude declaring them as enumerators.
Compare: ctype_base::space in C++03 subclause 22.2.1 [lib.category.ctype] versus the same in N4582 subclause 22.4.1 [category.ctype]. It is unclear whether this is intentional. Further it is unclear if odr-use of bitmask elements is intended to be allowed.[2016-05 Issues Telecom]
Jonathan believes that this was intentional, and was done by N3110. Jonathan will provide more precise references.
Proposed resolution:
Section: 20.13.4 [allocator.adaptor.members] Status: Tentatively NAD Submitter: Billy Robert O'Neal III Opened: 2016-05-24 Last modified: 2016-06-08
Priority: Not Prioritized
View other active issues in [allocator.adaptor.members].
View all other issues in [allocator.adaptor.members].
View all issues with Tentatively NAD status.
Discussion:
scoped_allocator_adaptor is specified to use forward when what it is really doing is moving elements. It should use move.
Previous resolution [SUPERSEDED]:
This wording is relative to N4582.
Edit 20.13.4 [allocator.adaptor.members] p15 as indicated:
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x);Effects: Equivalent to this->construct(p, piecewise_construct, forward_as_tuple(std::
forwardmove<U>(x.first)), forward_as_tuple(std::forwardmove<V>(x.second))).
Proposed resolution:
Withdrawn by the submitter, since the prerequisites were incorrect.