This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3614. `iota_view::size` and the most negative signed integer values

Section: 26.6.4.2 [range.iota.view] Status: New Submitter: Jiang An Opened: 2021-10-01 Last modified: 2021-10-14

Priority: 3

View all other issues in [range.iota.view].

View all issues with New status.

Discussion:

According to 26.6.4.2 [range.iota.view]/15, when both `W` and `Bound` are integer-like, the expression in the return statement uses `-value_` and `-bound_`. These operations result in undefined behavior when `-` is applied to the most negative integer value of a promoted type.

I believe that we can simply convert `value_` and `bound_` to the return type (`make-unsigned-like-t<common_type_t<W, Bound>>`) and then perform the subtraction. Such method should give the same results with UB eliminated.

Additionally, if we decide that `iota_view<uint8_t, uint8_t>(uint8_t(1)).size()` is well-defined (LWG 3597), it should give the correct result. We can truncate the result to fit the type `W`.

[2021-10-14; Reflector poll]

Set priority to 3 after reflector poll.

Proposed resolution:

This wording is relative to N4892.

> [Drafting Note: Two mutually exclusive options are prepared, depicted below by Option A and Option B, respectively.]

Option A: Just fixes the most negative values

1. Modify 26.6.4.2 [range.iota.view] as indicated:

   >     constexpr auto size() const requires see below;

   > > -15- Effects: Equivalent to:

   > > >     if constexpr (is-integer-like<W> && is-integer-like<Bound>) {
   > > >       return (value_ < 0)
   > > >         ? ((bound_ < 0)
   > > >           ? to-unsigned-like(-value_) - to-unsigned-like(-bound_)
   > > >           : to-unsigned-like(bound_) + to-unsigned-like(-value_))
   > > >         : to-unsigned-like(bound_) - to-unsigned-like(value_);
   > > >       using UC = make-unsigned-like-t<common_type_t<W, Bound>>;
   > > >       return UC(bound_) - UC(value_);
   > > >     } else
   > > >       return to-unsigned-like(bound_ - value_);

   > > -16- Remarks: […]

Option B: Also fixes pathological cases involving unsigned-integer-like types

1. Modify 26.6.4.2 [range.iota.view] as indicated:

   >     constexpr auto size() const requires see below;

   > > -15- Effects: Equivalent to:

   > > >     if constexpr (is-integer-like<W> && is-integer-like<Bound>) {
   > > >       return (value_ < 0)
   > > >         ? ((bound_ < 0)
   > > >           ? to-unsigned-like(-value_) - to-unsigned-like(-bound_)
   > > >           : to-unsigned-like(bound_) + to-unsigned-like(-value_))
   > > >         : to-unsigned-like(bound_) - to-unsigned-like(value_);
   > > >       using UC = make-unsigned-like-t<common_type_t<W, Bound>>;
   > > >       if constexpr (is-signed-integer-like<W>)
   > > >         return UC(bound_) - UC(value_);
   > > >       else
   > > >         return UC(W(UC(bound_) - UC(value_)));
   > > >     } else
   > > >       return to-unsigned-like(bound_ - value_);

   > > -16- Remarks: […]