Topic: [[derived]] attribute for CRTP.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 29 Sep 2015 07:27:43 -0700 (PDT)
Raw View
------=_Part_206_945212483.1443536863154
Content-Type: multipart/alternative;
boundary="----=_Part_207_304962640.1443536863161"
------=_Part_207_304962640.1443536863161
Content-Type: text/plain; charset=UTF-8
Hi all,
There is an ongoing effort to define a subset of C++ which is statically
checkable as memory safe. In particular the CppCoreGuidelines ban the use
of static_cast for down casting.
One common use of static_cast is for the CRTP pattern:
template<class Derived> struct Base
{
void foo() {
...
static_cast<Derived*>(this)->bar();
}
};
struct Derived : Base<Derived> {
void bar() { ... };
};
Which allow replacing some usages of the virtual Template Pattern with
templates, for performance and better type checking.
As shown, the patter is safe, as long as the Derived parameter of Base is
an actual Derived type of Base *and* the dynamic type of this is actually
derived. To conform to the guidelines, the static_cast would need to be
replaced with a dynamic_cast and a virtual function added in Base. This can
have performance consequences in addition of opening the road to failures
at runtime.
A simple way to enforce the restriction is to use an attribute:
template<class Derived>
[[derived(Derived)]]
struct Base {....};
Such attribute asserts that for any object of type T2 which has a base
class of type 'Base<T1>', either T2 is T1 or T1 is a direct or indirect
base of T2 and Base<T1> is a direct or indirect base of T1.
The semantic of the class definition with or without the attribute is
exactly the same. A compiler or static checker decide enforces such an
attribute will emit an error every time an object definition, new
expression or temporary would violate the assertion.
The alternative is to give the error at type definition instead of object
definition, which would help catch the error early and at the place it
actually occurs, but it might prevent otherwise safe constructs:
struct Intermediate : Base<Derived> {...}
struct Derived : Intermediate {};
Intermediate x; // this is invalid
Derived y; // this is ok
-- gpd
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_207_304962640.1443536863161
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi all,<br><br>There is an ongoing effort to define a subs=
et of C++ which is statically checkable as memory safe. In particular the C=
ppCoreGuidelines ban the use of static_cast for down casting.<br><br>One co=
mmon use of static_cast is for the CRTP pattern:<br><br>template<class D=
erived> struct Base<br>{<br>=C2=A0=C2=A0=C2=A0=C2=A0 void foo() {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast<Derived*=
>(this)->bar();<br>=C2=A0=C2=A0=C2=A0=C2=A0 }<br>};<br><br>struct Der=
ived : Base<Derived> {<br>=C2=A0=C2=A0=C2=A0=C2=A0 void bar() { ... }=
;<br>};<br><br>Which allow replacing some usages of the virtual Template Pa=
ttern with templates, for performance and better type checking.<br>As shown=
, the patter is safe, as long as the Derived parameter of Base is an actual=
Derived type of Base *and* the dynamic type of this is actually derived. T=
o conform to the guidelines, the static_cast would need to be replaced with=
a dynamic_cast and a virtual function added in Base. This can have perform=
ance consequences in addition of opening the road to failures at runtime.<b=
r><br>A simple way to enforce the restriction is to use an attribute: <br><=
br>template<class Derived><br>[[derived(Derived)]]<br>struct Base {..=
...};<br><br>Such attribute asserts that for any object of type T2 which has=
a base class of type 'Base<T1>', either T2 is T1 or T1 is a =
direct or indirect base of T2 and Base<T1> is a direct or indirect ba=
se of T1.<br><br>The semantic of the class definition with or without the a=
ttribute is exactly the same. A compiler or static checker decide enforces =
such an attribute will emit an error every time an object definition, new e=
xpression or temporary would violate the assertion.<br><br>The alternative =
is to give the error at type definition instead of object definition, which=
would help catch the error early and at the place it actually occurs, but =
it might prevent otherwise safe constructs:<br><br>struct Intermediate : Ba=
se<Derived> {...}<br>struct Derived : Intermediate {};<br><br>Interme=
diate x; // this is invalid<br>Derived y; // this is ok<br><br>-- gpd<br><b=
r><br><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_207_304962640.1443536863161--
------=_Part_206_945212483.1443536863154--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 29 Sep 2015 17:30:48 +0300
Raw View
On 29 September 2015 at 17:27, Giovanni Piero Deretta
<gpderetta@gmail.com> wrote:
> Hi all,
>
> There is an ongoing effort to define a subset of C++ which is statically
> checkable as memory safe. In particular the CppCoreGuidelines ban the use of
> static_cast for down casting.
See https://github.com/isocpp/CppCoreGuidelines/issues/83
> A simple way to enforce the restriction is to use an attribute:
>
> template<class Derived>
> [[derived(Derived)]]
> struct Base {....};
>
> Such attribute asserts that for any object of type T2 which has a base class
> of type 'Base<T1>', either T2 is T1 or T1 is a direct or indirect base of T2
> and Base<T1> is a direct or indirect base of T1.
Why don't you just make the constructor of Base protected?
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 29 Sep 2015 17:07:51 -0400
Raw View
--089e013d0ffcf769820520e93421
Content-Type: text/plain; charset=UTF-8
Could you just use static_assert and is_base_of ?
(and make sure static analysis tools recognize what you are doing)
On Tue, Sep 29, 2015 at 10:27 AM, Giovanni Piero Deretta <
gpderetta@gmail.com> wrote:
> Hi all,
>
> There is an ongoing effort to define a subset of C++ which is statically
> checkable as memory safe. In particular the CppCoreGuidelines ban the use
> of static_cast for down casting.
>
> One common use of static_cast is for the CRTP pattern:
>
> template<class Derived> struct Base
> {
> void foo() {
> ...
> static_cast<Derived*>(this)->bar();
> }
> };
>
> struct Derived : Base<Derived> {
> void bar() { ... };
> };
>
> Which allow replacing some usages of the virtual Template Pattern with
> templates, for performance and better type checking.
> As shown, the patter is safe, as long as the Derived parameter of Base is
> an actual Derived type of Base *and* the dynamic type of this is actually
> derived. To conform to the guidelines, the static_cast would need to be
> replaced with a dynamic_cast and a virtual function added in Base. This can
> have performance consequences in addition of opening the road to failures
> at runtime.
>
> A simple way to enforce the restriction is to use an attribute:
>
> template<class Derived>
> [[derived(Derived)]]
> struct Base {....};
>
> Such attribute asserts that for any object of type T2 which has a base
> class of type 'Base<T1>', either T2 is T1 or T1 is a direct or indirect
> base of T2 and Base<T1> is a direct or indirect base of T1.
>
> The semantic of the class definition with or without the attribute is
> exactly the same. A compiler or static checker decide enforces such an
> attribute will emit an error every time an object definition, new
> expression or temporary would violate the assertion.
>
> The alternative is to give the error at type definition instead of object
> definition, which would help catch the error early and at the place it
> actually occurs, but it might prevent otherwise safe constructs:
>
> struct Intermediate : Base<Derived> {...}
> struct Derived : Intermediate {};
>
> Intermediate x; // this is invalid
> Derived y; // this is ok
>
> -- gpd
>
>
>
> --
>
> ---
> 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
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e013d0ffcf769820520e93421
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><br></div>Could you just use static_assert and i=
s_base_of ?<br></div>(and make sure static analysis tools recognize what yo=
u are doing)<br><br><br></div><div class=3D"gmail_extra"><br><div class=3D"=
gmail_quote">On Tue, Sep 29, 2015 at 10:27 AM, Giovanni Piero Deretta <span=
dir=3D"ltr"><<a href=3D"mailto:gpderetta@gmail.com" target=3D"_blank">g=
pderetta@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr">Hi all,<br><br>There is an ongoing effort to define a subs=
et of C++ which is statically checkable as memory safe. In particular the C=
ppCoreGuidelines ban the use of static_cast for down casting.<br><br>One co=
mmon use of static_cast is for the CRTP pattern:<br><br>template<class D=
erived> struct Base<br>{<br>=C2=A0=C2=A0=C2=A0=C2=A0 void foo() {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast<Derived*=
>(this)->bar();<br>=C2=A0=C2=A0=C2=A0=C2=A0 }<br>};<br><br>struct Der=
ived : Base<Derived> {<br>=C2=A0=C2=A0=C2=A0=C2=A0 void bar() { ... }=
;<br>};<br><br>Which allow replacing some usages of the virtual Template Pa=
ttern with templates, for performance and better type checking.<br>As shown=
, the patter is safe, as long as the Derived parameter of Base is an actual=
Derived type of Base *and* the dynamic type of this is actually derived. T=
o conform to the guidelines, the static_cast would need to be replaced with=
a dynamic_cast and a virtual function added in Base. This can have perform=
ance consequences in addition of opening the road to failures at runtime.<b=
r><br>A simple way to enforce the restriction is to use an attribute: <br><=
br>template<class Derived><br>[[derived(Derived)]]<br>struct Base {..=
...};<br><br>Such attribute asserts that for any object of type T2 which has=
a base class of type 'Base<T1>', either T2 is T1 or T1 is a =
direct or indirect base of T2 and Base<T1> is a direct or indirect ba=
se of T1.<br><br>The semantic of the class definition with or without the a=
ttribute is exactly the same. A compiler or static checker decide enforces =
such an attribute will emit an error every time an object definition, new e=
xpression or temporary would violate the assertion.<br><br>The alternative =
is to give the error at type definition instead of object definition, which=
would help catch the error early and at the place it actually occurs, but =
it might prevent otherwise safe constructs:<br><br>struct Intermediate : Ba=
se<Derived> {...}<br>struct Derived : Intermediate {};<br><br>Interme=
diate x; // this is invalid<br>Derived y; // this is ok<span class=3D"HOEnZ=
b"><font color=3D"#888888"><br><br>-- gpd<br><br><br><br></font></span></di=
v><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e013d0ffcf769820520e93421--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 29 Sep 2015 19:16:13 -0700 (PDT)
Raw View
------=_Part_3204_1912231557.1443579373977
Content-Type: multipart/alternative;
boundary="----=_Part_3205_1617152890.1443579373977"
------=_Part_3205_1617152890.1443579373977
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, September 29, 2015 at 7:27:43 AM UTC-7, Giovanni Piero Deretta=
=20
wrote:
>
>
> There is an ongoing effort to define a subset of C++ which is statically=
=20
> checkable as memory safe. In particular the CppCoreGuidelines ban the use=
=20
> of static_cast for down casting.
>
> One common use of static_cast is for the CRTP pattern:
>
> template<class Derived> struct Base
> {
> void foo() {
> ...
> static_cast<Derived*>(this)->bar();
> }
> };
>
As I understand it from Bjarne and Herb's CppCon talks about the=20
CppCoreGuidelines, this isn't an egregious violation of the Guidelines.
Or rather, it *is*, but it's a violation committed by the implementor of=20
the CRTP base class, not the user of the CRTP base class.
If I'm implementing a CRTP base class, then yeah, I'm going to have to use=
=20
a downward static_cast; just as if I'm implementing a smart pointer class,=
=20
yeah, I'm going to have to use an owning raw pointer. At a certain low=20
level, you have to break the guidelines in order to help implement them.
Maybe it's worth catching, since a dumb user could write
class Foo : Base<Bar> { ... };
and then Base<Bar>::foo() would try to downcast itself to a Bar and=20
everything would break. That's not the CRTP-base-class author's fault;=20
that's really the user's fault, and so it would be nice to be able to catch=
=20
the bug mechanically.
What is the current state-of-the-art for catching CRTP-engendered bugs such=
=20
as
struct S : std::enable_shared_from_this<S> { auto f() { return=20
shared_from_this(); } };
struct T : std::enable_shared_from_this<S> { auto f() { return=20
shared_from_this(); } };
?
Finally(!), I'll suggest that the obvious spelling for this feature would b=
e
template<class D> struct Base final(D) {
// ...
};
i.e., just as an unadorned "final" in that position means "nobody can=20
inherit from me", "final(Ts...)" in that position should mean "nobody but=
=20
Ts... (or anyone who visibly inherits from Ts...) can inherit from me."
I don't think this feature is a good idea (I don't like C++11 "final"=20
because it breaks a lot of cute metaprogramming tricks involving=20
inheritance, and because IMO it should have been an attribute to begin=20
with), but if this feature were to be adopted, that would be the spelling=
=20
of it, IMHO.
=E2=80=93Arthur
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3205_1617152890.1443579373977
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, September 29, 2015 at 7:27:43 AM UTC-7, Giovan=
ni Piero Deretta wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><br>There is an ongoing effort to define a subset of C++ which is=
statically checkable as memory safe. In particular the CppCoreGuidelines b=
an the use of static_cast for down casting.<br><br>One common use of static=
_cast is for the CRTP pattern:<br><br>template<class Derived> struct =
Base<br>{<br>=C2=A0=C2=A0=C2=A0=C2=A0 void foo() {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast<Derived*>(this)-><wb=
r>bar();<br>=C2=A0=C2=A0=C2=A0=C2=A0 }<br>};<br></div></blockquote><div><br=
></div><div>As I understand it from Bjarne and Herb's CppCon talks abou=
t the CppCoreGuidelines, this isn't an egregious violation of the Guide=
lines.</div><div>Or rather, it *is*, but it's a violation committed by =
the implementor of the CRTP base class, not the user of the CRTP base class=
..</div><div>If I'm implementing a CRTP base class, then yeah, I'm g=
oing to have to use a downward static_cast; just as if I'm implementing=
a smart pointer class, yeah, I'm going to have to use an owning raw po=
inter. At a certain low level, you have to break the guidelines in order to=
help implement them.</div><div><br></div><div>Maybe it's worth catchin=
g, since a dumb user could write</div><div><br></div><div>=C2=A0 =C2=A0 cla=
ss Foo : Base<Bar> { ... };</div><div><br></div><div>and then Base<=
;Bar>::foo() would try to downcast itself to a Bar and everything would =
break. That's not the CRTP-base-class author's fault; that's re=
ally the user's fault, and so it would be nice to be able to catch the =
bug mechanically.</div><div><br></div><div>What is the current state-of-the=
-art for catching CRTP-engendered bugs such as</div><div><br></div><div><di=
v>=C2=A0 =C2=A0 struct S : std::enable_shared_from_this<S> { auto f()=
{ return shared_from_this(); } };</div><div>=C2=A0 =C2=A0 struct T : std::=
enable_shared_from_this<S> { auto f() { return shared_from_this(); } =
};</div></div><div><br></div><div>?</div><div><br></div><div>Finally(!), I&=
#39;ll suggest that the obvious spelling for this feature would be</div><di=
v><br></div><div>=C2=A0 =C2=A0 template<class D> struct Base final(D)=
{</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 // ...</div><div>=C2=A0 =C2=A0 };<=
/div><div><br></div><div>i.e., just as an unadorned "final" in th=
at position means "nobody can inherit from me", "final(Ts...=
)" in that position should mean "nobody but Ts... (or anyone who =
visibly inherits from Ts...) can inherit from me."</div><div><br></div=
><div>I don't think this feature is a good idea (I don't like C++11=
"final" because it breaks a lot of cute metaprogramming tricks i=
nvolving inheritance, and because IMO it should have been an attribute to b=
egin with), but if this feature were to be adopted, that would be the spell=
ing of it, IMHO.</div><div><br></div><div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3205_1617152890.1443579373977--
------=_Part_3204_1912231557.1443579373977--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 30 Sep 2015 03:13:05 -0700 (PDT)
Raw View
------=_Part_144_1208639417.1443607985432
Content-Type: multipart/alternative;
boundary="----=_Part_145_1094820203.1443607985432"
------=_Part_145_1094820203.1443607985432
Content-Type: text/plain; charset=UTF-8
On Tuesday, September 29, 2015 at 3:30:50 PM UTC+1, Ville Voutilainen wrote:
>
> On 29 September 2015 at 17:27, Giovanni Piero Deretta
> <gpde...@gmail.com <javascript:>> wrote:
> > Hi all,
> >
> > There is an ongoing effort to define a subset of C++ which is statically
> > checkable as memory safe. In particular the CppCoreGuidelines ban the
> use of
> > static_cast for down casting.
>
> See https://github.com/isocpp/CppCoreGuidelines/issues/83
>
>
yes, and the exception need to marked explicitly so that the static checker
can validate it.
> > A simple way to enforce the restriction is to use an attribute:
> >
> > template<class Derived>
> > [[derived(Derived)]]
> > struct Base {....};
> >
> > Such attribute asserts that for any object of type T2 which has a base
> class
> > of type 'Base<T1>', either T2 is T1 or T1 is a direct or indirect base
> of T2
> > and Base<T1> is a direct or indirect base of T1.
>
> Why don't you just make the constructor of Base protected?
>
That's fine to mitigate issues, but the whole point of the attribute is to
statically validating the memory safety of as much code as possible. A
protected constructor wouldn't help in this example:
struct Foo;
struct Bad : Base<Foo> {} x;
-- gpd
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_145_1094820203.1443607985432
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Tuesday, September 29, 2015 at 3:30:50 PM UTC+1, Ville Voutilain=
en wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 29 September 2015 =
at 17:27, Giovanni Piero Deretta
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
A923nCH-CQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">gpde...@gmail.com</a>> wrote:
<br>> Hi all,
<br>>
<br>> There is an ongoing effort to define a subset of C++ which is stat=
ically
<br>> checkable as memory safe. In particular the CppCoreGuidelines ban =
the use of
<br>> static_cast for down casting.
<br>
<br>See <a href=3D"https://github.com/isocpp/CppCoreGuidelines/issues/83" t=
arget=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fisocpp%2FCppCoreGuidelines=
%2Fissues%2F83\46sa\75D\46sntz\0751\46usg\75AFQjCNGgxKYNtjEuOWUoC4WrybiyhcT=
MqA';return true;" onclick=3D"this.href=3D'https://www.google.com/u=
rl?q\75https%3A%2F%2Fgithub.com%2Fisocpp%2FCppCoreGuidelines%2Fissues%2F83\=
46sa\75D\46sntz\0751\46usg\75AFQjCNGgxKYNtjEuOWUoC4WrybiyhcTMqA';return=
true;">https://github.com/isocpp/<wbr>CppCoreGuidelines/issues/83</a>
<br>
<br></blockquote><div>=C2=A0</div><div>yes, and the exception need to marke=
d explicitly so that the static checker can validate it.<br>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">> A simple way to enforce the =
restriction is to use an attribute:
<br>>
<br>> template<class Derived>
<br>> [[derived(Derived)]]
<br>> struct Base {....};
<br>>
<br>> Such attribute asserts that for any object of type T2 which has a =
base class
<br>> of type 'Base<T1>', either T2 is T1 or T1 is a direc=
t or indirect base of T2
<br>> and Base<T1> is a direct or indirect base of T1.
<br>
<br>Why don't you just make the constructor of Base protected?
<br></blockquote><div><br>That's fine to mitigate issues, but the whole=
point of the attribute is to statically validating the memory safety of as=
much code as possible. A protected constructor wouldn't help in this e=
xample:<br><br>=C2=A0 struct Foo;<br>=C2=A0 struct Bad : Base<Foo> {}=
x; <br><br>-- gpd<br><br><br>=C2=A0</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_145_1094820203.1443607985432--
------=_Part_144_1208639417.1443607985432--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 30 Sep 2015 13:33:12 +0300
Raw View
On 30 September 2015 at 13:13, Giovanni Piero Deretta
<gpderetta@gmail.com> wrote:
>
>
> On Tuesday, September 29, 2015 at 3:30:50 PM UTC+1, Ville Voutilainen wrote:
>>
>> On 29 September 2015 at 17:27, Giovanni Piero Deretta
>> <gpde...@gmail.com> wrote:
>> > Hi all,
>> >
>> > There is an ongoing effort to define a subset of C++ which is statically
>> > checkable as memory safe. In particular the CppCoreGuidelines ban the
>> > use of
>> > static_cast for down casting.
>>
>> See https://github.com/isocpp/CppCoreGuidelines/issues/83
>>
>
> yes, and the exception need to marked explicitly so that the static checker
> can validate it.
Unless the checker will be more lenient about CRTP cases.
>> > A simple way to enforce the restriction is to use an attribute:
>> >
>> > template<class Derived>
>> > [[derived(Derived)]]
>> > struct Base {....};
>> >
>> > Such attribute asserts that for any object of type T2 which has a base
>> > class
>> > of type 'Base<T1>', either T2 is T1 or T1 is a direct or indirect base
>> > of T2
>> > and Base<T1> is a direct or indirect base of T1.
>>
>> Why don't you just make the constructor of Base protected?
>
>
> That's fine to mitigate issues, but the whole point of the attribute is to
> statically validating the memory safety of as much code as possible. A
> protected constructor wouldn't help in this example:
>
> struct Foo;
> struct Bad : Base<Foo> {} x;
Correct, it's not fool-proof - other people pointed out checking
is_base_of, which
would be an additional possibility to make problems less likely in CRTP bases.
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 30 Sep 2015 03:56:00 -0700 (PDT)
Raw View
------=_Part_4468_6971267.1443610560528
Content-Type: multipart/alternative;
boundary="----=_Part_4469_1574149336.1443610560529"
------=_Part_4469_1574149336.1443610560529
Content-Type: text/plain; charset=UTF-8
On Wednesday, September 30, 2015 at 11:33:16 AM UTC+1, Ville Voutilainen
wrote:
>
> On 30 September 2015 at 13:13, Giovanni Piero Deretta
> <gpde...@gmail.com <javascript:>> wrote:
> >
> >
> > On Tuesday, September 29, 2015 at 3:30:50 PM UTC+1, Ville Voutilainen
> wrote:
> >>
> >> On 29 September 2015 at 17:27, Giovanni Piero Deretta
> >> <gpde...@gmail.com> wrote:
> >> > Hi all,
> >> >
> >> > There is an ongoing effort to define a subset of C++ which is
> statically
> >> > checkable as memory safe. In particular the CppCoreGuidelines ban the
> >> > use of
> >> > static_cast for down casting.
> >>
> >> See https://github.com/isocpp/CppCoreGuidelines/issues/83
> >>
> >
> > yes, and the exception need to marked explicitly so that the static
> checker
> > can validate it.
>
> Unless the checker will be more lenient about CRTP cases.
>
>
The whole point of the checker proposed by Stroustrup and Sutter is that it
doesn't have false negatives (only false positives) *and* the checking
doesn't require whole program analysis. The checker will have to flag any
static_cast to derived in base unless something in the declaration of Base
itself marks it safe.
-- gpd
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4469_1574149336.1443610560529
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, September 30, 2015 at 11:33:16 AM UTC+1, Ville Voutilainen wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">On 30 September 2015 at 13=
:13, Giovanni Piero Deretta
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
VNyIb78_CgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">gpde...@gmail.com</a>> wrote:
<br>>
<br>>
<br>> On Tuesday, September 29, 2015 at 3:30:50 PM UTC+1, Ville Voutilai=
nen wrote:
<br>>>
<br>>> On 29 September 2015 at 17:27, Giovanni Piero Deretta
<br>>> <<a>gpde...@gmail.com</a>> wrote:
<br>>> > Hi all,
<br>>> >
<br>>> > There is an ongoing effort to define a subset of C++ whic=
h is statically
<br>>> > checkable as memory safe. In particular the CppCoreGuidel=
ines ban the
<br>>> > use of
<br>>> > static_cast for down casting.
<br>>>
<br>>> See <a href=3D"https://github.com/isocpp/CppCoreGuidelines/iss=
ues/83" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'=
https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fisocpp%2FCppCoreG=
uidelines%2Fissues%2F83\46sa\75D\46sntz\0751\46usg\75AFQjCNGgxKYNtjEuOWUoC4=
WrybiyhcTMqA';return true;" onclick=3D"this.href=3D'https://www.goo=
gle.com/url?q\75https%3A%2F%2Fgithub.com%2Fisocpp%2FCppCoreGuidelines%2Fiss=
ues%2F83\46sa\75D\46sntz\0751\46usg\75AFQjCNGgxKYNtjEuOWUoC4WrybiyhcTMqA=
9;;return true;">https://github.com/isocpp/<wbr>CppCoreGuidelines/issues/83=
</a>
<br>>>
<br>>
<br>> yes, and the exception need to marked explicitly so that the stati=
c checker
<br>> can validate it.
<br>
<br>Unless the checker will be more lenient about CRTP cases.
<br>
<br></blockquote><div><br>The whole point of the checker proposed by Strous=
trup and Sutter is that it doesn't have false negatives (only false pos=
itives) *and* the checking doesn't require whole program analysis. The =
checker will have to flag any static_cast to derived in base unless somethi=
ng in the declaration of Base itself marks it safe.<br><br>-- gpd<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4469_1574149336.1443610560529--
------=_Part_4468_6971267.1443610560528--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 02 Oct 2015 11:08:22 -0400
Raw View
On 2015-09-29 10:27, Giovanni Piero Deretta wrote:
> There is an ongoing effort to define a subset of C++ which is statically=
=20
> checkable as memory safe. In particular the CppCoreGuidelines ban the use=
=20
> of static_cast for down casting.
>=20
> One common use of static_cast is for the CRTP pattern:
>=20
> template<class Derived> struct Base
> {
> void foo() {
> ...
> static_cast<Derived*>(this)->bar();
> }
> };
As noted in the inline classes thread=C2=B9, CRTP in general could use some
love. What I'd *really* prefer is a way to declare a CRTP class such
that 'this' is *implicitly* converted to the derived type on any use.
That is, name lookup is delayed until the derived type is known. IOW,
this would work:
/* new syntax */ Base
{
int foo()
{
return /*this->*/bar(); // note: no member 'bar' in Base
}
};
class Foo : Base // note: class type not repeated
{
int bar() { return 1; }
};
Foo f;
auto i =3D f.foo(); // Calls Foo::bar
assert(i =3D=3D 1);
Now you just don't need to cast at all (not explicitly, anyway; the
compiler does it for you). Naturally, the compiler would also enforce
correct usage... which is *also* harder to screw up in the first place
because you aren't repeating the class name any more.
There is room for debate if derived members should be preferred always
over base members, or only if qualified, and if a qualified call shall
be an error if the derived class has no such member. (And of course
other syntax questions that I didn't even attempt to suggest.) I think
this would be far more useful than a mere attribute, however. Ideally,
we would be able to kill off CRTP entirely... not the concept, but in
the sense that it is "CRTP".
(=C2=B9
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/u35GIuJECcQ/mtju=
TF8ECAAJ)
--=20
Matthew
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Fri, 2 Oct 2015 18:01:41 +0200
Raw View
On 09/29/2015 04:27 PM, Giovanni Piero Deretta wrote:
> One common use of static_cast is for the CRTP pattern:
Another use is to cast from an underlying type to an enum class
(e.g. for protocol deserialization.)
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.