libstdc++: potential bug in specification of layouts.

Luc Grosheintz luc.grosheintz@gmail.com
Fri May 16 11:18:07 GMT 2025


I'd like to ask about a sixth observation.

On 5/13/25 11:51 AM, Luc Grosheintz wrote:
> This email chain continues a discussion about potential bugs in the
> specification that was started here:
> https://gcc.gnu.org/pipermail/libstdc++/2025-May/061350.html
> 
> For notational convenience, I'll write `layout_left` as shorthand for
> `layout_left::mapping`, e.g. layout_left::required_span_size, refers to
> layout_left::mapping<Extents>::required_span_size.
> 
> 
> 1. operator==
> 
> The observation is that for rank0 and rank1, two mappings, one of type
> layout_left<Extents> and the other layout_right<OExtents>, the
> operator== is ambiguous if `Extents == OExtents`; but not if the extents
> are convertible (because the convertability is only in one direction).
> 
> Godbolt: https://godbolt.org/z/35TbMnc1e
> 
> Resolution: It's not clear to me what to propose. Likely, something that
> fixes the ambiguity issue to allow comparing all rank 0 and rank 1
> instances of layout_left and layout_right. Help would be most welcome:
> either by collaboratively working on the proposed change; or if someone
> wants to take over completely that would also work.
> 
> 
> 2. Missing `noexcept` in layout_left.
> 
> The specification (N4950 and as published on `eel.is`) consistently
> doesn't mention `noexcept` in both the Overview and Constructors
> sections for `layout_left(layout_stride)`.
> 
> https://eel.is/c++draft/mdspan.layout.left#overview-1
> https://eel.is/c++draft/mdspan.layout.left#lib:layout_left::mapping,constructor____
> 
> Resolution: I suggest that I file an issue to add `noexcept`
> consistently. Can this be considered an editorial issue?
> 
> 
> 3. Inconsistency about `constexpr` in layout_right::required_span_size.
> 
> The section Overview specifies that `required_span_size` must be
> constexpr. In the section Observers this keyword is missing.
> 
> I believe this is considered an editorial issue; and I can fix it by
> submitting a PR to the text of the standard.
> 
> https://eel.is/c++draft/mdspan.layout.right#overview-1
> https://eel.is/c++draft/mdspan.layout.right.obs#lib:required_span_size,layout_right::mapping
> 
> Resolution: I suggest that I file an editorial issue.
> 
> 
> 4. Inconsistency about `noexcept` in `layout_left::stride`.
> 
> The section Overview mentions it's `noexcept` but the section Observers
> doesn't. Again, I think this is an editorial issue.
> 
> https://eel.is/c++draft/mdspan.layout.left#overview-1
> https://eel.is/c++draft/mdspan.layout.left.obs#lib:stride,layout_left::mapping
> 
> Resolution: I suggest that I file an editorial issue.
> 
> 
> 5. At Rank 0 layout_stride is untypically convertible.
> 
> Commonly, two layouts are considered convertible, if the underlying
> extent_types are convertible, e.g.
> 
> https://eel.is/c++draft/mdspan.layout.left.cons#lib:layout_left::mapping,constructor_
> https://eel.is/c++draft/mdspan.layout.left.cons#lib:layout_left::mapping,constructor__
> https://eel.is/c++draft/mdspan.layout.right.cons#lib:layout_right::mapping,constructor_
> https://eel.is/c++draft/mdspan.layout.right.cons#lib:layout_right::mapping,constructor__
> https://eel.is/c++draft/mdspan.layout.stride.cons#9
> 
> However, for the two ctors `layout_left(layout_stride)` and
> `layout_right(layout_stride)`, the condition is `rank > 0`. Therefore,
> 
>      using E1 = std::extents<int>;
>      using E2 = std::extents<unsigned int>;
> 
>      static_assert(std::is_convertible_v<
>          std::layout_stride::mapping<E2>,
>          std::layout_right::mapping<E1>
>        >);
> 
> even though:
> 
>      static_assert(!std::is_convertible_v<E2, E1>);
> 
> https://eel.is/c++draft/mdspan.layout.left.cons#lib:layout_left::mapping,constructor____
> https://eel.is/c++draft/mdspan.layout.right.cons#lib:layout_right::mapping,constructor____
> 
> Moreover, for rank 0 layout_stride can be converted to any
> specialization of layout_left or layout_right; but not to every
> specialization of `layout_stride`.
> 
> Godbolt: https://godbolt.org/z/MdbvafG7n
> 
> Resolution: I suggest I create an non-editorial issue to propose adding
> the convertibility criterium to the explicitness condition.

6. layout_{left,right}::stride is missing for rank == 0

For rank == 0 both layout_left and layout_right are missing a method
stride(rank_type).

https://eel.is/c++draft/mdspan.layout.left.obs#5
https://eel.is/c++draft/mdspan.layout.right.obs#5

I suspect this leads to an inconsistency within the standard, because it
means that neither layout_left nor layout_right meet the layout mapping
policy [1]; even though the standard says they must [2].

[1]: https://eel.is/c++draft/mdspan.layout#reqmts-1.5
      https://eel.is/c++draft/mdspan.layout#reqmts-itemdecl:12
[2]: https://eel.is/c++draft/mdspan.layout#policy.overview-1

Note that both define:
     static constexpr bool is_strided() noexcept { return true; }

The fact that the methods are missing often leads to code like:
   if constexpr (rank > 0)
     for(size_t i = 0; i < rank; ++i)
       // something with `m.stride(i)`.


More information about the Libstdc++ mailing list