https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96042

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to gcc-bugs from comment #2)
> I think this is too easy to say that this is not a "bug", we can also weaken
> the terminology and say "potential-inconsistency".
> 
> Technically you are right, but only because there seems to be a specific
> "exception" for the implementation does not mean that this is the right
> thing to do.

I disagree. In the strongest possible terms.

> <unhappy-end-user - ignore this>
> I personally don't understand why the standard allows exceptions outside
> it's echo-system, I guess the stdlib implementers understand the subject
> better when forming the standard, and are lobbing harder for their
> necessities which is sometimes different from the needs / expectation of the
> end-user.
> </unhappy-end-user- ignore this>

This has nothing to do with our own necessities, this is to support end users.

> Can you help me figure out in which cases `-std=c++2a` would produce this
> type? Or asked differently: In which cases, other than this, do I encounter
> a `__int128` from using only types and functions defined in the standard?

I'm not aware of any others currently. That could change in future if the C and
C++ standards are changed to allow types larger than long long to be treated as
standard integer types. I would be very happy to see the ideas described in
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2425.pdf happen.

> I have the feeling from your answer that this type is an everyday type.

No. It's not, and that's exactly why we used it for IOTA-DIFF-T.

> Looking at https://eel.is/c++draft/range.iota#view-1, and if I read it
> correctly, this is case 3:
> 
> > Otherwise, IOTA-DIFF-T(W) is an unspecified signed-integer-like type
> > ([iterator.concept.winc]) of width not less than the width of W.
> > 
> > [Note: It is unspecified whether this type satisfies
> > weakly_­incrementable. — end note]
> 
> It means it would be totally fine to return the signed version of `size_t`,
> because it has at least the same width. (This would be a valid option, too)

But it wouldn't be totally fine, because that type (i.e. ptrdiff_t) cannot
represent the difference between the begin and end iterators of
iota_view<size_t, SIZE_MAX>.

The whole point of allowing IOTA-DIFF-T to be an unspecified integer-like type
is to solve that problem. It has to be a type larger than size_t, otherwise you
can't use large iota_view types, and that make a different group of users
unhappy.

Our implementation will soon be updated to use a custom class type that behaves
like an integer, so that we can also represent the maximum difference for
iota_view<unsigned __int128, (unsigned __int128)-1>. Will you still complain
that "it is unexpected that I get a type that is not described in the
standard"? 

It's **not possible** to represent the difference type of iota_view<W,B> for
every W without using a type that isn't in the set of types allowed for W. See
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1522r1.pdf for the
background.

Why is using __int128 here a problem? Do you really think we should treat "I am
surprised by this" as a more serious concern than "Some specializations of
iota_view have undefined bhaviour because the alternative would surprise some
people"?

You being unhappy because you don't expect something can (I hope) be resolved
by explaining the pragmatic engineering reasons behind the decision. Some code
being impossible to write cannot really be explained just by saying "we know
how to make this work, but it made somebody sad so we decided not to support
it, sorry".

The problem here seems to be that you expect the difference type of an
iota_view to be a normal integer type. Your expectation is wrong. You should
change your expectation.

Reply via email to