Skip to content

Commit 193dc9d

Browse files
committed
New issue from Nikolas Klauser: "num_put::do_put and void pointers"
1 parent 375e904 commit 193dc9d

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

xml/issue4216.xml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4216" status="New">
5+
<title>`num_put::do_put` and `void` pointers</title>
6+
<section>
7+
<sref ref="[facet.num.put.virtuals]"/>
8+
</section>
9+
<submitter>Nikolas Klauser</submitter>
10+
<date>26 Feb 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
The `num_put::do_put` overloads are defined in terms of `printf`.
16+
However, it is not clear what the intended behaviour of pointers is.
17+
<p/>
18+
While the `num_put` wording makes a quite clear statement that it should
19+
be whatever `printf("%p", ptr)` would be, `num_get` is entirely silent
20+
on which function should be used. This makes it entirely unclear whether
21+
round-tripping is supposed to work. It's also not clear whether
22+
`num_put` was just simple to specify via `printf` or whether the intent
23+
was that the output matches in all cases. Round-tripping between
24+
`num_put` and `num_get` was broken in libc++ until recently. However, to
25+
fix that, the output of `num_put::do_put` no longer matches the libc's
26+
`printf` in all cases. libstdc++ had this behaviour since at least two
27+
decades, indicating that nobody seems to have a problem with
28+
`num_put::do_put` and `printf` having different results in some rare cases.
29+
</p>
30+
</discussion>
31+
32+
<resolution>
33+
<p>
34+
This wording is relative to <paper num="N5001"/>.
35+
</p>
36+
37+
<ol>
38+
<li><p>Modify <sref ref="[facet.num.put.virtuals]"/> as indicated:</p>
39+
40+
<blockquote>
41+
<pre>
42+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, long val) const;
43+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, long long val) const;
44+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, unsigned long val) const;
45+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, unsigned long long val) const;
46+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, double val) const;
47+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, long double val) const;
48+
iter_type do_put(iter_type out, ios_base&amp; str, char_type fill, const void* val) const;
49+
</pre>
50+
<blockquote>
51+
<p>
52+
-1- <i>Effects</i>: [&hellip;]
53+
<p/>
54+
-2- The details of this operation occur in several stages: [&hellip;]
55+
<p/>
56+
-3- Detailed descriptions of each stage follow.
57+
<p/>
58+
-4- <i>Returns</i>: <tt>out</tt>.
59+
<p/>
60+
<b>Stage 1</b>: The first action of stage 1 is to determine a conversion specifier. [&hellip;]
61+
<p/>
62+
For conversion from `void*` the specifier is `%p`.
63+
<p/>
64+
The representations at the end of stage 1 consists of the `char`'s that would be printed by a call of
65+
`printf(s, val)` where `s` is the conversion specifier determined above<ins>, except that any
66+
implementation-defined behavior of `printf` may be different from a call to `printf`</ins>.
67+
</p>
68+
</blockquote>
69+
</blockquote>
70+
</li>
71+
72+
</ol>
73+
74+
</resolution>
75+
76+
</issue>

0 commit comments

Comments
 (0)