[PATCH 1/2] libstdc++: Implement P3725R3 Filter View Extensions for Safer Use
Jonathan Wakely
jwakely@redhat.com
Wed Apr 1 16:03:23 GMT 2026
On Wed, 1 Apr 2026 at 15:50, Patrick Palka <ppalka@redhat.com> wrote:
>
> On Tue, 31 Mar 2026, Jonathan Wakely wrote:
>
> > On Tue, 31 Mar 2026 at 19:43, Patrick Palka <ppalka@redhat.com> wrote:
> > >
> > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk and
> > > eventually backports?
> >
> > OK for trunk, yes. Thanks for doing this so quickly!
>
> Thanks for the review.
>
> >
> > For the backports we should either not do it, or add separate
> > _CIterator and _CSentinel instead of changing the iterator and
> > sentinel into templates, so that we don't change the ABI of the
> > existing non-const filter_view::begin() and filter_view::end()
> > members.
> > Otherwise we'd change the return types of those functions in a dot
> > release (15.3 and 14.4) which is not what people expect/want when
> > updating within a stable release.
>
> Ah, makes sense. Agreed in principle, but I was struggling to think of
> a concrete scenario that'd actually cause user breakage with this change,
> (i.e. changing the mangling of a user-visible implementation-detail type
> that is nonetheless layout-compatible with the original type). I thought
> layout-compatibility would be enough to avoid breakage, but that's not
> true.
>
> If a user-defined function depends on the type of the filter_view
> iterator, e.g.:
>
> inline void f(auto& it) { }
> ...
> auto v = r | views::filter(p);
> f(v.begin());
>
> and one TU with such an f call was compiled before the change, and
> another such TU was compiled after the change, then the two TUs now
> refer to logically distinct functions, with different manglings and
> addresses. This could be problematic if user code stores their address
> across TUs and later compares it. Also any static local variables
> within f won't be merged by the linker and we'll end up with two copies
> thereof. Unlikely, but theoretically possible breakage, so still
> must be avoided on a release branch.
>
> I think we could avoid changing the mangling of the original _Iterator
> in a relatively concise way with:
>
> struct _Iterator : _GIterator<_Iterator, false>
> { using _GIterator<false>::_GIterator; };
>
> where _GIterator is a CRTP version of the new generic iterator class
> template. The mangling of _Iterator's member functions would still
> change but I believe that's fine because user code can't take the
> address of such standard member functions (and so the mangling of
> user-defined functions can't depend on _Iterator's member functions).
I think you'd need to override operator++ and operator-- because the
ones in the base class will return the base class, not the derived
class :-(
More information about the Libstdc++
mailing list