C++ Standard Library Issues to be moved in [INSERT CURRENT MEETING HERE]

Doc. no. R0165???
Date:

Revised 2018-11-29 at 03:02:05 UTC

Project: Programming Language C++
Reply to: Marshall Clow <lwgchair@gmail.com>

Ready Issues


3012(i). atomic<T> is unimplementable for non-is_trivially_copy_constructible T

Section: 30.7 [atomics.types.generic] Status: Ready Submitter: Billy O'Neal III Opened: 2017-08-16 Last modified: 2018-11-11

Priority: 2

View all other issues in [atomics.types.generic].

View all issues with Ready status.

Discussion:

30.7 [atomics.types.generic] requires that T for std::atomic is trivially copyable. Unfortunately, that's not sufficient to implement atomic. Consider atomic<T>::load, which wants to look something like this:

template<class T>
struct atomic {
  __compiler_magic_storage_for_t storage;

  T load(memory_order = memory_order_seq_cst) const {
    return __magic_intrinsic(storage);
  }

};

Forming this return statement, though, requires that T is copy constructible — trivially copyable things aren't necessarily copyable! For example, the following is trivially copyable but breaks libc++, libstdc++, and msvc++:

struct NonAssignable {
  int i;
  NonAssignable() = delete;
  NonAssignable(int) : i(0) {}
  NonAssignable(const NonAssignable&) = delete;
  NonAssignable(NonAssignable&&) = default;
  NonAssignable& operator=(const NonAssignable&) = delete;
  NonAssignable& operator=(NonAssignable&&) = delete;
  ~NonAssignable() = default;
};

All three standard libraries are happy as long as T is trivially copy constructible, assignability is not required. Casey Carter says that we might want to still require trivially copy assignable though, since what happens when you do an atomic<T>::store is morally an "assignment" even if it doesn't use the user's assignment operator.

[2017-11 Albuquerque Wednesday issue processing]

Status to Open; Casey and STL to work with Billy for better wording.

Should this include trivially copyable as well as trivially copy assignable?

2017-11-09, Billy O'Neal provides updated wording.

Previous resolution [SUPERSEDED]:

This resolution is relative to N4687.

  1. Edit 30.7 [atomics.types.generic] as indicated:

    -1- If is_trivially_copy_constructible_v<T> is false, the program is ill-formedThe template argument for T shall be trivially copyable (6.7 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]

Previous resolution [SUPERSEDED]:

This resolution is relative to N4687.

  1. Edit 30.7 [atomics.types.generic] as indicated:

    -1- If is_copy_constructible_v<T> is false or if is_trivially_copyable_v<T> is false, the program is ill-formedThe template argument for T shall be trivially copyable (6.7 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]

[2017-11-12, Tomasz comments and suggests alternative wording]

According to my understanding during Albuquerque Saturday issue processing we agreed that we want the type used with the atomics to have non-deleted and trivial copy/move construction and assignment.

Wording note: CopyConstructible and CopyAssignable include semantic requirements that are not checkable at compile time, so these are requirements imposed on the user and cannot be validated by an implementation without heroic efforts.

[2018-11 San Diego Thursday night issue processing]

Status to Ready.

Proposed resolution:

This resolution is relative to N4700.

  1. Edit 30.7 [atomics.types.generic] as indicated:

    -1- The template argument for T shall meet the CopyConstructible and CopyAssignable requirements. If is_trivially_copyable_v<T> && is_copy_constructible_v<T> && is_move_constructible_v<T> && is_copy_assignable_v<T> && is_move_assignable_v<T> is false, the program is ill-formedbe trivially copyable (6.7 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]


3040(i). basic_string_view::starts_with Effects are incorrect

Section: 20.4.2.6 [string.view.ops] Status: Tentatively Ready Submitter: Marshall Clow Opened: 2017-11-29 Last modified: 2018-11-11

Priority: 0

View all other issues in [string.view.ops].

View all issues with Tentatively Ready status.

Discussion:

The effects of starts_with are described as equivalent to return compare(0, npos, x) == 0.

This is incorrect, because it returns false when you check to see if any sequence begins with the empty sequence. (There are other failure cases, but that one's easy)

As a drive-by fix, we can make the Effects: for starts_with and ends_with clearer.

Those are the second and proposed third changes, and they are not required.

[ 2017-12-13 Moved to Tentatively Ready after 8 positive votes for P0 on c++std-lib. ]

Previous resolution: [SUPERSEDED]

This wording is relative to N4713.

  1. Change 20.4.2.6 [string.view.ops] p20 as indicated:

    constexpr bool starts_with(basic_string_view x) const noexcept;

    -20- Effects: Equivalent to: return size() >= x.size() && compare(0, nposx.size(), x) == 0;

  2. Change 20.4.2.6 [string.view.ops] p21 as indicated:

    constexpr bool starts_with(charT x) const noexcept;

    -21- Effects: Equivalent to: return !empty() && traits::eq(front(), x)starts_with(basic_string_view(&x, 1));

  3. Change 20.4.2.6 [string.view.ops] p24 as indicated:

    constexpr bool ends_with(charT x) const noexcept;

    -24- Effects: Equivalent to: return !empty() && traits::eq(back(), x)ends_with(basic_string_view(&x, 1));

[2018-01-23, Reopening due to a comment of Billy Robert O'Neal III requesting a change of the proposed wording]

The currently suggested wording has:

Effects: Equivalent to: return size() >= x.size() && compare(0, x.size(), x) == 0;

but compare() already does the size() >= x.size() check.

It seems like it should say:

Effects: Equivalent to: return substr(0, x.size()) == x;

[ 2018-10-29 Moved to Tentatively Ready after 5 positive votes for P0 on c++std-lib. ]

Proposed resolution:

This wording is relative to N4713.

  1. Change 20.4.2.6 [string.view.ops] p20 as indicated:

    constexpr bool starts_with(basic_string_view x) const noexcept;

    -20- Effects: Equivalent to: return substr(0, x.size()) == xcompare(0, npos, x) == 0;

  2. Change 20.4.2.6 [string.view.ops] p21 as indicated:

    constexpr bool starts_with(charT x) const noexcept;

    -21- Effects: Equivalent to: return !empty() && traits::eq(front(), x)starts_with(basic_string_view(&x, 1));

  3. Change 20.4.2.6 [string.view.ops] p24 as indicated:

    constexpr bool ends_with(charT x) const noexcept;

    -24- Effects: Equivalent to: return !empty() && traits::eq(back(), x)ends_with(basic_string_view(&x, 1));


3087(i). One final &x in §[list.ops]

Section: 21.3.10.5 [list.ops] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-03-19 Last modified: 2018-11-11

Priority: 3

View other active issues in [list.ops].

View all other issues in [list.ops].

View all issues with Tentatively Ready status.

Discussion:

LWG 3017 missed an instance of &x in 21.3.10.5 [list.ops] p14.

[2018-06-18 after reflector discussion]

Priority set to 3

[2018-10-15 Status to Tentatively Ready after seven positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4727.

  1. Edit 21.3.10.5 [list.ops] as indicated:

    void splice(const_iterator position, list& x, const_iterator first,
                const_iterator last);
    void splice(const_iterator position, list&& x, const_iterator first,
                const_iterator last);
    

    -11- Requires: […]

    -12- Effects: […]

    -13- Throws: Nothing.

    -14- Complexity: Constant time if &addressof(x) == this; otherwise, linear time.


3101(i). span's Container constructors need another constraint

Section: 21.7.3.2 [span.cons] Status: Tentatively Ready Submitter: Stephan T. Lavavej Opened: 2018-04-12 Last modified: 2018-11-11

Priority: 1

View all other issues in [span.cons].

View all issues with Tentatively Ready status.

Discussion:

When I overhauled span's constructor constraints, I was careful about the built-in array, std::array, and converting span constructors. These types contain bounds information, so we can achieve safety at compile-time by permitting implicit conversions if and only if the destination extent is dynamic (this accepts anything by recording the size at runtime) or the source and destination extents are identical. However, I missed the fact that the Container constructors are the opposite case. A Container (e.g. a vector) has a size that's known only at runtime. It's safe to convert this to a span with dynamic_extent, but for consistency and safety, this shouldn't implicitly convert to a span with fixed extent. (The more verbose (ptr, count) and (first, last) constructors are available to construct fixed extent spans from runtime-length ranges. Note that debug precondition checks are equally possible with the Container and (ptr, count)/(first, last) constructors. The issue is that implicit conversions are notoriously problematic, so they should be permitted only when they are absolutely known to be safe.)

[2018-04-24 Priority set to 1 after discussion on the reflector.]

[2018-06 Rapperswil Thursday issues processing]

Status to LEWG. Should this be ill-formed, or fail at runtime if the container is too small? Discussion on the reflector here.

[2018-11 San Diego Saturday]

LEWG said that they're fine with the proposed resolution. Status to Tentatively Ready.

Proposed resolution:

This wording is relative to N4741.

  1. Edit 21.7.3.2 [span.cons] as indicated:

    template<class Container> constexpr span(Container& cont);
    template<class Container> constexpr span(const Container& cont);
    

    -14- Requires: [data(cont), data(cont) + size(cont)) shall be a valid range. If extent is not equal to dynamic_extent, then size(cont) shall be equal to extent.

    -15- Effects: Constructs a span that is a view over the range [data(cont), data(cont) + size(cont)).

    -16- Postconditions: size() == size(cont) && data() == data(cont).

    -17- Throws: What and when data(cont) and size(cont) throw.

    -18- Remarks: These constructors shall not participate in overload resolution unless:

    1. (18.?) — extent == dynamic_extent,

    2. (18.1) — Container is not a specialization of span,

    3. (18.2) — Container is not a specialization of array,

    4. […]


3119(i). Program-definedness of closure types

Section: 99 [defns.program.defined.spec] Status: Ready Submitter: Hubert Tong Opened: 2018-06-09 Last modified: 2018-11-11

Priority: 2

View all issues with Ready status.

Discussion:

The description of closure types in 7.5.5.1 [expr.prim.lambda.closure] says:

An implementation may define the closure type differently […]

The proposed resolution to LWG 2139 defines a "program-defined type" to be a

class type or enumeration type that is not part of the C++ standard library and not defined by the implementation, or an instantiation of a program-defined specialization

I am not sure that the intent of whether closure types are or are not program-defined types is clearly conveyed by the wording.

[2018-06-23 after reflector discussion]

Priority set to 2

[2018-08-14 Casey provides additional discussion and a Proposed Resolution]

We use the term "program-defined" in the library specification to ensure that two users cannot create conflicts in a component in namespace std by specifying different behaviors for the same type. For example, we allow users to specialize common_type when at least one of the parameters is a program-defined type. Since two users cannot define the same program-defined type, this rule prevents two users (or libraries) defining the same specialization of std::common_type.

Since it's guaranteed that even distinct utterances of identical lambda expressions produce closures with distinct types (7.5.5.1 [expr.prim.lambda.closure]), adding closure types to our term "program-defined type" is consistent with the intended use despite that such types are technically defined by the implementation.

Previous resolution [SUPERSEDED]:

This wording is relative to N4762.

[2018-08-23 Batavia Issues processing]

Updated wording

[2018-11 San Diego Thursday night issue processing]

Status to Ready.

Proposed resolution:

This wording is relative to N4762.