Issue 4243: as_bytes/as_writable_bytes is broken with span (original) (raw)


This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

4243. as_bytes/as_writable_bytes is broken with span<volatile T>

Section: 23.7.2.3 [span.objectrep] Status: WP Submitter: Hewill Kang Opened: 2025-04-12 Last modified: 2025-11-11

Priority: 4

View all issues with WP status.

Discussion:

They both use reinterpret_cast to cast the underlying pointer type of span to const byte*and byte* respectively, which leads to a hard error when the element type is volatile-qualified (demo):

#include

int main() { std::span span; auto bytes = as_bytes(span); // hard error auto writable_bytes = as_writable_bytes(span); // hard error }

Previous resolution [SUPERSEDED]:

This wording is relative to N5008.

  1. Modify 23.7.2.1 [span.syn], header <span> synopsis, as indicated:

    […]
    namespace std {
    […]
    // 23.7.2.3 [span.objectrep], views of object representation
    template<class ElementType, size_t Extent>
    span<const conditional_t<is_volatile_v, volatile byte, byte>,
    Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>

 as_bytes(span<ElementType, Extent> s) noexcept;  

template<class ElementType, size_t Extent>
span<conditional_t<is_volatile_v, volatile byte, byte>,
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
as_writable_bytes(span<ElementType, Extent> s) noexcept;
} 2. Modify 23.7.2.3 [span.objectrep] as indicated:
template<class ElementType, size_t Extent>
span<const conditional_t<is_volatile_v, volatile byte, byte>,
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
as_bytes(span<ElementType, Extent> s) noexcept;

-1- Effects: Equivalent to:return R{reinterpret_cast<R::pointer~~const byte*~~>(s.data()), s.size_bytes()};
where R is the return type.

template<class ElementType, size_t Extent>
span<conditional_t<is_volatile_v, volatile byte, byte>,
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
as_writable_bytes(span<ElementType, Extent> s) noexcept;

-2- Constraints: is_const_v<ElementType> is false.

-3- Effects: Equivalent to:return R{reinterpret_cast<R::pointer~~byte*~~>(s.data()), s.size_bytes()};
where R is the return type.

[2025-04-16; Hewill Kang provides alternative wording]

Based on reflector feedback, the revised wording just improves the current state of not supporting support for volatile.

[2025-06-12; Reflector poll]

Set priority to 4 after reflector poll.

[Sofia 2025-06-17; Move to Ready]

[Kona 2025-11-08; Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N5008.

  1. Modify 23.7.2.3 [span.objectrep] as indicated:

    template<class ElementType, size_t Extent>
    span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
    as_bytes(span<ElementType, Extent> s) noexcept;

    -?- Constraints: is_volatile_v<ElementType> is false.

    -1- Effects: Equivalent to: return R{reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
    where R is the return type.

    template<class ElementType, size_t Extent>
    span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
    as_writable_bytes(span<ElementType, Extent> s) noexcept;

    -2- Constraints: is_const_v<ElementType> is false andis_volatile_v<ElementType> is false.

    -3- Effects: Equivalent to: return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};
    where R is the return type.