Topic: p0035r2 comments


Author: Sean Middleditch <sean.middleditch@gmail.com>
Date: Sat, 2 Apr 2016 13:08:38 -0700 (PDT)
Raw View
------=_Part_2603_56319085.1459627718546
Content-Type: multipart/alternative;
 boundary="----=_Part_2604_1756099539.1459627718546"

------=_Part_2604_1756099539.1459627718546
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Apologies if any of these were already brought up in Jacksonville.

Regarding separate memory arenas for over-aligned type, the paper states: "=
But=20
in a well-written, portable C++ program, at the point where memory is=20
deallocated, the type of the object being deleted =E2=80=94 and therefore w=
hether=20
it is over-aligned =E2=80=94 is known."

This very common C++ example illustrates that this is not at all=20
universally true:

// overaligned type
struct alignas(128) padded_int { int i; };

// polymorphic types
class base { virtual ~base(); };
class derived : public base { padded_int pi; };

// allocation of over-aligned type stored in pointer to non-over-aligned=20
base
base* b =3D new derived;

// deletion of over-aligned object that does not know the actual type of=20
the over-aligned object
delete b;

This is likely to cause many very surprising bugs in real-world C++ code=20
that incrementally adopts over-aligned types and global allocators. Given=
=20
the rather numerous other applications of either having global arenas or=20
smarter deallocation routines that can select the appropriate arena for a=
=20
block (memory accounting, polymorphic allocators, etc.). I have no good=20
thoughts on how to actually address this other than just stating clearly in=
=20
the standard that we do not intend to support certain older allocator=20
models with all new language features and that some vendors will need to=20
improve the default global allocator shipping with their implementations.


Regarding the system alignment threshold, the paper states: "In this=20
revision, I have chosen to use a predefined macro for this purpose."

I feel like me might all agree that this should be a constexpr value=20
instead. The paper later states that implementations will "use a macro=20
anyway" but that's not really the standard's problem. Any implementation=20
that can ship a header with a macro can also ship a header with a C++=20
constexpr value. They can even just define it as static constexpr size_t=20
allocation_alignment_threshold_thingy =3D VENDOR_ALIGNMENT_THRESHOLD; We=20
should of course standardize the name and location of the constexpr value=
=20
allocation_alignment_threshold_thingy.


A further suggestion I have would be to gently suggest that implementations=
=20
emit a diagnostic if an over-aligned type is being allocated with the=20
global alignment-unaware allocator. The case of the class-specific=20
alignment-unaware allocator for over-aligned types being explicitly correct=
=20
for the type is of course quite common, as spelled out by the paper, making=
=20
a diagnostic in such a case harder to justify. That is unfortunate as it=20
opens yet another way for new code to be broken by mistake with no=20
diagnostic just in order to avoid making users run something like=20
clang-tidy on their existing codebase. :/

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d1063303-1835-4822-ba3c-54dd8541b011%40isocpp.or=
g.

------=_Part_2604_1756099539.1459627718546
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Apologies if any of these were already brought up in Jacks=
onville.<div><br></div><div><font face=3D"arial, sans-serif" size=3D"2">Reg=
arding separate memory arenas for over-aligned type, the paper states: &quo=
t;<span style=3D"color: rgb(0, 0, 0);">But in a well-written, portable C++ =
program, at the point where memory is deallocated, the type of the object b=
eing deleted =E2=80=94 and therefore whether it is over-aligned =E2=80=94 i=
s known.&quot;</span></font></div><div><font face=3D"arial, sans-serif" siz=
e=3D"2"><span style=3D"color: rgb(0, 0, 0);"><br></span></font></div><div><=
font face=3D"arial, sans-serif" size=3D"2"><span style=3D"color: rgb(0, 0, =
0);">This very common C++ example illustrates that this is not at all unive=
rsally true:</span></font></div><div><font face=3D"arial, sans-serif" size=
=3D"2"><span style=3D"color: rgb(0, 0, 0);"><br></span></font></div><blockq=
uote style=3D"margin: 0 0 0 40px; border: none; padding: 0px;"><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// overaligned type</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> alignas</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">128</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> padded_int=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// polymorphic types</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">base<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">virtual</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">~</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">base</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> derived </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">public</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">base</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> padd=
ed_int pi</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// allocation of over-aligne=
d type stored in pointer to non-over-aligned base</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">base</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> b </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">new</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> derived</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// deletion of over-align=
ed object that does not know the actual type of the over-aligned object</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">delete</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span></div></code></div><div>=
<font face=3D"arial, sans-serif" size=3D"2"><font color=3D"#660066"><br></f=
ont></font></div></blockquote><div><font face=3D"arial, sans-serif" size=3D=
"2">This is likely to cause many very surprising bugs in real-world C++ cod=
e that incrementally adopts over-aligned types and global allocators. Given=
 the rather numerous other applications of either having global arenas or s=
marter deallocation routines that can select the appropriate arena for a bl=
ock (memory accounting, polymorphic allocators, etc.). I have no good thoug=
hts on how to actually address this other than just stating clearly in the =
standard that we do not intend to support certain older allocator models wi=
th all new language features and that some vendors will need to improve the=
 default global allocator shipping with their implementations.</font></div>=
<div><font face=3D"arial, sans-serif" size=3D"2"><br></font></div><div><fon=
t face=3D"arial, sans-serif" size=3D"2"><br></font></div><div><font face=3D=
"arial, sans-serif" size=3D"2">Regarding the system alignment threshold, th=
e paper states: &quot;<span style=3D"color: rgb(0, 0, 0);">In this revision=
, I have chosen to use a predefined macro for this purpose.&quot;</span></f=
ont></div><div><font face=3D"arial, sans-serif" size=3D"2"><span style=3D"c=
olor: rgb(0, 0, 0);"><br></span></font></div><div><font size=3D"2"><span st=
yle=3D"color: rgb(0, 0, 0);"><font face=3D"arial, sans-serif">I feel like m=
e might all agree that this should be a constexpr value instead. The paper =
later states that implementations will &quot;use a macro anyway&quot; but t=
hat&#39;s not really the standard&#39;s problem. Any implementation that ca=
n ship a header with a macro can also ship a header with a C++ constexpr va=
lue. They can even just define it as </font><font face=3D"courier new, mono=
space">static constexpr size_t </font></span></font><span style=3D"color: r=
gb(0, 0, 0); font-family: &#39;courier new&#39;, monospace; font-size: smal=
l;">allocation_</span><span style=3D"color: rgb(0, 0, 0); font-family: &#39=
;courier new&#39;, monospace; font-size: small;">alignment_threshold_thingy=
=C2=A0</span><font size=3D"2"><span style=3D"color: rgb(0, 0, 0);"><font fa=
ce=3D"courier new, monospace">=3D=C2=A0VENDOR_ALIGNMENT_THRESHOLD;</font><f=
ont face=3D"arial, sans-serif"> We should of course standardize the name an=
d location of the constexpr value=C2=A0</font><font face=3D"courier new, mo=
nospace">allocation_alignment_threshold_thingy</font><font face=3D"arial, s=
ans-serif">.</font></span></font></div><div><font size=3D"2"><span style=3D=
"color: rgb(0, 0, 0);"><font face=3D"arial, sans-serif"><br></font></span><=
/font></div><div><font size=3D"2"><span style=3D"color: rgb(0, 0, 0);"><fon=
t face=3D"arial, sans-serif"><br></font></span></font></div><div><font size=
=3D"2"><span style=3D"color: rgb(0, 0, 0);"><font face=3D"arial, sans-serif=
">A further suggestion I have would be to gently suggest that implementatio=
ns emit a diagnostic if an over-aligned type is being allocated with the gl=
obal alignment-unaware allocator. The case of the class-specific alignment-=
unaware allocator for over-aligned types being explicitly correct for the t=
ype is of course quite common, as spelled out by the paper, making a diagno=
stic in such a case harder to justify. That is unfortunate as it opens yet =
another way for new code to be broken by mistake with no diagnostic just in=
 order to avoid making users run something like clang-tidy on their existin=
g codebase. :/</font></span></font></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d1063303-1835-4822-ba3c-54dd8541b011%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d1063303-1835-4822-ba3c-54dd8541b011=
%40isocpp.org</a>.<br />

------=_Part_2604_1756099539.1459627718546--
------=_Part_2603_56319085.1459627718546--

.


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Mon, 4 Apr 2016 00:22:20 +0900
Raw View
On 2016/04/03 5:08 +0900, Sean Middleditch wrote:
> Regarding separate memory arenas for over-aligned type, the paper states:=
 "But=20
> in a well-written, portable C++ program, at the point where memory is=20
> deallocated, the type of the object being deleted =E2=80=94 and therefore=
 whether=20
> it is over-aligned =E2=80=94 is known."
>=20
> This very common C++ example illustrates that this is not at all=20
> universally true:
>=20
> // overaligned type
> struct alignas(128) padded_int { int i; };
>=20
> // polymorphic types
> class base { virtual ~base(); };
> class derived : public base { padded_int pi; };
>=20
> // allocation of over-aligned type stored in pointer to non-over-aligned=
=20
> base
> base* b =3D new derived;
>=20
> // deletion of over-aligned object that does not know the actual type of=
=20
> the over-aligned object
> delete b;

I think this won't be a problem, because C++ already requires to select
a deallocation function by the actual type in that case.

From the latest draft (N4582) 12.5 [class.free] p4
> Class-specific deallocation function lookup is a part of general
> deallocation function lookup (5.3.5) and occurs as follows. If the
> delete-expression is used to deallocate a class object whose static type
> has a virtual destructor, the deallocation function is the one selected
> at the point of definition of the dynamic type's virtual destructor.

Typical implementations use a virtual call to "deallocating destructor".

  struct base { base(); virtual ~base(); };
  void f(base* b) { delete b; }

  struct derived : public base {
    derived(); ~derived();

    // the above f() must do the right job even if it doesn't know
    // whether a derived class has a specific deallocation function.
    void operator delete(void*);
  };
  derived::derived() {}
  derived::~derived() {}

Please see the following assembly output, and that the code for f()
isn't changed even if you remove the declaration of the
derived::operator delete().
https://godbolt.org/g/phgsO7

--=20
k_satoda

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5701352C.7000903%40f2.dion.ne.jp.

.