Skip to content

Commit 3b1d9b0

Browse files
committed
New issue from Giuseppe D'Angelo: "Imprecise Throws: clause in std::relocate"
1 parent ba10a8a commit 3b1d9b0

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

xml/issue4282.xml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4282" status="New">
5+
<title>Imprecise <i>Throws</i>: clause in `std::relocate`</title>
6+
<section>
7+
<sref ref="[obj.lifetime]"/>
8+
</section>
9+
<submitter>Giuseppe D'Angelo</submitter>
10+
<date>23 Jun 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
The current specification of `std::relocate` in <sref ref="[obj.lifetime]"/> says
16+
</p>
17+
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;">
18+
<p>
19+
<i>Throws</i>: Nothing.
20+
</p>
21+
</blockquote>
22+
<p>
23+
This is imprecise. A trivially relocatable type may feature a throwing
24+
move constructor (or a throwing destructor); for instance, a linked-list
25+
implementation with an externally allocated sentinel node may have a
26+
throwing move constructor, but still be trivially relocatable. Such a
27+
type is nothrow relocatable (as per `is_nothrow_relocatable_v`, cf.
28+
<sref ref="[meta.unary.prop]"/>) and therefore one can call `std::relocate`
29+
on objects of that type.
30+
<p/>
31+
During constant evaluation, a call to `std::relocate` is specified to
32+
relocate objects via move construction and destruction.
33+
(`std::trivially_relocate` is unavailable during constant evaluation.)
34+
<p/>
35+
Since <paper num="P3068"/> we are allowed to throw during constant evaluation,
36+
and therefore it's unclear whether `std::relocate` should propagate such an
37+
exception to the caller or should instead make the evaluation not a
38+
constant expression (and therefore make the program ill-formed, since by
39+
construction we end up in this possibility during constant evaluation).
40+
<p/>
41+
Given the rationale brought forward for `std::relocate` in <paper num="P2786"/>
42+
is to be always a nofail operation, I'm proposing a resolution that goes in
43+
that direction.
44+
</p>
45+
</discussion>
46+
47+
<resolution>
48+
<p>
49+
This wording is relative to <paper num="N5008"/>.
50+
</p>
51+
52+
<ol>
53+
<li><p>Modify <sref ref="[obj.lifetime]"/> as indicated:</p>
54+
55+
<blockquote>
56+
<pre>
57+
template&lt;class T&gt;
58+
constexpr T* relocate(T* first, T* last, T* result);
59+
</pre>
60+
<blockquote>
61+
<p>
62+
-16 <i>Mandates</i>: [&hellip;]
63+
<p/>
64+
-17- <i>Preconditions</i>: [&hellip;]
65+
<p/>
66+
-18- <i>Effects</i>: [&hellip;]
67+
<p/>
68+
-19- <i>Returns</i>: `result + (last - first)`.
69+
<p/>
70+
-20- <i>Throws:</i>: Nothing.
71+
<p/>
72+
<ins>-?- <i>Remarks</i>: If `relocate` is called during constant evaluation, and an
73+
exception is thrown by a constructor or destructor of `T`, the call to `relocate`
74+
is not a core constant expression (<sref ref="[expr.const]"/>).</ins>
75+
<p/>
76+
[<i>Note 3</i>: Overlapping ranges are supported. &mdash; <i>end note</i>]
77+
</p>
78+
</blockquote>
79+
</blockquote>
80+
</li>
81+
82+
</ol>
83+
</resolution>
84+
85+
</issue>

0 commit comments

Comments
 (0)