[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