Skip to content

Commit 3125961

Browse files
committed
New issue from Hewill: "as_bytes/as_writable_bytes is broken with span<volatile T>"
1 parent 86164be commit 3125961

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

xml/issue4243.xml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4243" status="New">
5+
<title>`as_bytes`/`as_writable_bytes` is broken with <code>span&lt;volatile T&gt;</code></title>
6+
<section>
7+
<sref ref="[span.objectrep]"/>
8+
</section>
9+
<submitter>Hewill Kang</submitter>
10+
<date>12 Apr 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
They both use `reinterpret_cast` to cast the underlying pointer type of `span` to `const byte*`
16+
and `byte*` respectively, which leads to a hard error when the element type is `volatile`-qualified
17+
(<a href="https://godbolt.org/z/Eq4ovzTEK">demo</a>):
18+
</p>
19+
<blockquote><pre>
20+
#include &lt;span&gt;
21+
22+
int main() {
23+
std::span&lt;volatile int&gt; span;
24+
auto bytes = as_bytes(span); // <span style="color:#C80000;font-weight:bold">hard error</span>
25+
auto writable_bytes = as_writable_bytes(span); // <span style="color:#C80000;font-weight:bold">hard error</span>
26+
}
27+
</pre></blockquote>
28+
</discussion>
29+
30+
<resolution>
31+
<p>
32+
This wording is relative to <paper num="N5008"/>.
33+
</p>
34+
35+
<ol>
36+
37+
<li><p>Modify <sref ref="[span.syn]"/>, header <tt>&lt;span&gt;</tt> synopsis, as indicated:</p>
38+
39+
<blockquote>
40+
<pre>
41+
[&hellip;]
42+
namespace std {
43+
[&hellip;]
44+
<i>// <sref ref="[span.objectrep]"/>, views of object representation</i>
45+
template&lt;class ElementType, size_t Extent&gt;
46+
span&lt;const <ins>conditional_t&lt;is_volatile_v&lt;ElementType&gt;, volatile byte, </ins>byte<ins>&gt;</ins>,
47+
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent&gt;
48+
as_bytes(span&lt;ElementType, Extent&gt; s) noexcept;
49+
50+
template&lt;class ElementType, size_t Extent&gt;
51+
span&lt;<ins>conditional_t&lt;is_volatile_v&lt;ElementType&gt;, volatile byte, </ins>byte<ins>&gt;</ins>,
52+
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent&gt;
53+
as_writable_bytes(span&lt;ElementType, Extent&gt; s) noexcept;
54+
}
55+
</pre>
56+
</blockquote>
57+
58+
</li>
59+
60+
<li><p>Modify <sref ref="[span.objectrep]"/> as indicated:</p>
61+
62+
<blockquote>
63+
<pre>
64+
template&lt;class ElementType, size_t Extent&gt;
65+
span&lt;const <ins>conditional_t&lt;is_volatile_v&lt;ElementType&gt;, volatile byte, </ins>byte<ins>&gt;</ins>,
66+
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent&gt;
67+
as_bytes(span&lt;ElementType, Extent&gt; s) noexcept;
68+
</pre>
69+
<blockquote>
70+
<p>
71+
-1- <i>Effects</i>: Equivalent to:
72+
<code>return R{reinterpret_cast&lt;<ins>R::pointer</ins><del>const byte*</del>&gt;(s.data()), s.size_bytes()};</code><br/>
73+
where `R` is the return type.
74+
</p>
75+
</blockquote>
76+
<pre>
77+
template&lt;class ElementType, size_t Extent&gt;
78+
span&lt;<ins>conditional_t&lt;is_volatile_v&lt;ElementType&gt;, volatile byte, </ins>byte<ins>&gt;</ins>,
79+
Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent&gt;
80+
as_writable_bytes(span&lt;ElementType, Extent&gt; s) noexcept;
81+
</pre>
82+
<blockquote>
83+
<p>
84+
-2- <i>Constraints</i>: <code>is_const_v&lt;ElementType&gt;</code> is `false`.
85+
</p>
86+
</blockquote>
87+
<blockquote>
88+
<p>
89+
-3- <i>Effects</i>: Equivalent to:
90+
<code>return R{reinterpret_cast&lt;<ins>R::pointer</ins><del>byte*</del>&gt;(s.data()), s.size_bytes()};</code><br/>
91+
where `R` is the return type.
92+
</p>
93+
</blockquote>
94+
</blockquote>
95+
96+
</li>
97+
98+
</ol>
99+
</resolution>
100+
101+
</issue>

0 commit comments

Comments
 (0)