[PATCH v2] libstdc++: Use hidden friends for __normal_iterator operators

Stephan Bergmann sberg.fun@gmail.com
Sun Jul 6 18:53:25 GMT 2025


On 6/12/25 10:46, Jonathan Wakely wrote:
> It now says:
> 
>     I also had to reorder the __attribute__((always_inline)) and
>     [[nodiscard]] attributes on the pre-c++20 operators, because Clang won't
>     allow [[foo]] after __attribute__((bar)) on a friend function:
> 
>     <source>:4:36: error: an attribute list cannot appear here
>         4 |     __attribute__((always_inline)) [[nodiscard]] friend bool
>           |                                    ^~~~~~~~~~~~~

Just noting that at least with recent Clang 21 trunk,

> $ cat test.cc
> #include <iterator>

> $ clang++ -std=c++17 -fsyntax-only test.cc
> In file included from test.cc:1:
> In file included from ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/iterator:65:
> ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/bits/stl_iterator.h:1252:37: error: 
>       an attribute list cannot appear here
>  1252 |         __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
>       |                                            ^~~~~~~~~~~~~~~~~~
> ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/x86_64-pc-linux-gnu/bits/c++config.h:173:29: note: 
>       expanded from macro '_GLIBCXX_NODISCARD'
>   173 | # define _GLIBCXX_NODISCARD [[__nodiscard__]]
>       |                             ^~~~~~~~~~~~~~~~~
> In file included from test.cc:1:
> In file included from ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/iterator:65:
> ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/bits/stl_iterator.h:1269:37: error: 
>       an attribute list cannot appear here
>  1269 |         __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
>       |                                            ^~~~~~~~~~~~~~~~~~
> ~/gcc/inst/lib/gcc/x86_64-pc-linux-gnu/16.0.0/../../../../include/c++/16.0.0/x86_64-pc-linux-gnu/bits/c++config.h:173:29: note: 
>       expanded from macro '_GLIBCXX_NODISCARD'
>   173 | # define _GLIBCXX_NODISCARD [[__nodiscard__]]
>       |                             ^~~~~~~~~~~~~~~~~
> 2 errors generated.

now fails (while with --std=c++20) it works, where something like

> diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
> index a7188f46f6d..26bb0206375 100644
> --- a/libstdc++-v3/include/bits/stl_iterator.h
> +++ b/libstdc++-v3/include/bits/stl_iterator.h
> @@ -1248,8 +1248,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>        // Random access iterator requirements
>        template<typename _Iter>
> +       __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
>         friend
> -       __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
> +       _GLIBCXX_CONSTEXPR
>         inline bool
>         operator<(const __normal_iterator& __lhs,
>                   const __normal_iterator<_Iter, _Container>& __rhs)
> @@ -1265,8 +1266,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>        { return __lhs.base() < __rhs.base(); }
>  
>        template<typename _Iter>
> +       __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
>         friend
> -       __attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
> +       _GLIBCXX_CONSTEXPR
>         bool
>         operator>(const __normal_iterator& __lhs,
>                   const __normal_iterator<_Iter, _Container>& __rhs)

would fix that.


More information about the Libstdc++ mailing list