Topic: Attribute for real constness (e.g., [[immutable]])


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 10 Dec 2015 11:38:25 -0800
Raw View
On Thursday 10 December 2015 16:37:54 'Edward Catmur' via ISO C++ Standard -
Future Proposals wrote:
> > > Can the compiler assume that a const-ref parameter will not be modified?
>
> It's only UB if the object referenced by the parameter is actually const
> (that is, the cv-qualifiers on its type at its point of declaration contain
> const).

Right. So

 int i = 0;
 function(i); // takes by const ref
 assert(i == 0);

Can the compiler assume i wasn't modified?

> > > Can the compiler assume that a const method will not modify non-mutable
> > > members?
>
> Again, no; it can be UB to const_cast away const on this if the object is
> actually const, but otherwise it is legit. So, calling an opaque
> const-qualified member function on a non-const object may well modify
> members (as long as they themselves are not declared const).

Thanks, that would be:

struct S
{
 int i;
 void function() const;
};

 S s = { 0 };
 s.function();
 assert(s.i == 0);

Given that the compiler cannot make the assumptions I marked in the assert,
can we have an attribute that lets the compiler know that the function
promises not to modify it?

I'd wager that over 99% of uses of const a really const, but the compiler
cannot optimise the code based on the constness. For example:

 std::string s = someFunction();
 if (!s.empty()) {
  doSomething(s);  // an out-of-line function taking const ref
  return s.at(0);   // <--- HERE
 }
 return '\0';

The at() function is allowed to throw std::out_of_range. I'd like the compiler
to optimise based on the fact that the string *isn't* empty in that place
because it wasn't empty before the out-of-line call.

The [[pure]] attribute would do the trick, but it would not allow for fine-
grained control. It might be interesting to keep one argument immutable but
not others.

Opinions?




--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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: tsvetan.dimitrov76@gmail.com
Date: Thu, 10 Dec 2015 12:28:21 -0800 (PST)
Raw View
------=_Part_55_768081327.1449779302049
Content-Type: multipart/alternative;
 boundary="----=_Part_56_61648598.1449779302049"

------=_Part_56_61648598.1449779302049
Content-Type: text/plain; charset=UTF-8



On Thursday, December 10, 2015 at 9:38:58 PM UTC+2, Thiago Macieira wrote:
>
> On Thursday 10 December 2015 16:37:54 'Edward Catmur' via ISO C++ Standard
> -
> Future Proposals wrote:
> > > > Can the compiler assume that a const-ref parameter will not be
> modified?
> >
> > It's only UB if the object referenced by the parameter is actually const
> > (that is, the cv-qualifiers on its type at its point of declaration
> contain
> > const).
>
> Right. So
>
>         int i = 0;
>         function(i);        // takes by const ref
>         assert(i == 0);
>
> Can the compiler assume i wasn't modified?
>
> > > > Can the compiler assume that a const method will not modify
> non-mutable
> > > > members?
> >
> > Again, no; it can be UB to const_cast away const on this if the object
> is
> > actually const, but otherwise it is legit. So, calling an opaque
> > const-qualified member function on a non-const object may well modify
> > members (as long as they themselves are not declared const).
>
> Thanks, that would be:
>
> struct S
> {
>         int i;
>         void function() const;
> };
>
>         S s = { 0 };
>         s.function();
>         assert(s.i == 0);
>
> Given that the compiler cannot make the assumptions I marked in the
> assert,
> can we have an attribute that lets the compiler know that the function
> promises not to modify it?
>
> I'd wager that over 99% of uses of const a really const, but the compiler
> cannot optimise the code based on the constness. For example:
>
>         std::string s = someFunction();
>         if (!s.empty()) {
>                 doSomething(s);                // an out-of-line function
> taking const ref
>                 return s.at(0);                        // <--- HERE
>         }
>         return '\0';
>
> The at() function is allowed to throw std::out_of_range. I'd like the
> compiler
> to optimise based on the fact that the string *isn't* empty in that place
> because it wasn't empty before the out-of-line call.
>
> The [[pure]] attribute would do the trick, but it would not allow for
> fine-
> grained control. It might be interesting to keep one argument immutable
> but
> not others.
>
> Opinions?
>
>
>
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
> How about just adding immutable as another qualifier. That way casting
away constness would be impossible and we'll finally have real consts.

--

---
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_56_61648598.1449779302049
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Thursday, December 10, 2015 at 9:38:58 PM UTC+2, Thiago Macieira=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Thursday 10 December=
 2015 16:37:54 &#39;Edward Catmur&#39; via ISO C++ Standard -=20
<br>Future Proposals wrote:
<br>&gt; &gt; &gt; Can the compiler assume that a const-ref parameter will =
not be modified?
<br>&gt;=20
<br>&gt; It&#39;s only UB if the object referenced by the parameter is actu=
ally const
<br>&gt; (that is, the cv-qualifiers on its type at its point of declaratio=
n contain
<br>&gt; const).
<br>
<br>Right. So
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int i =3D 0;
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0function(i);=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// takes by const ref
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0assert(i =3D=3D 0);
<br>
<br>Can the compiler assume i wasn&#39;t modified?
<br>
<br>&gt; &gt; &gt; Can the compiler assume that a const method will not mod=
ify non-mutable
<br>&gt; &gt; &gt; members?
<br>&gt;=20
<br>&gt; Again, no; it can be UB to const_cast away const on this if the ob=
ject is
<br>&gt; actually const, but otherwise it is legit. So, calling an opaque
<br>&gt; const-qualified member function on a non-const object may well mod=
ify
<br>&gt; members (as long as they themselves are not declared const).
<br>
<br>Thanks, that would be:
<br>
<br>struct S
<br>{
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int i;
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0void function() const;
<br>};
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0S s =3D { 0 };
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0s.function();
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0assert(s.i =3D=3D 0);
<br>
<br>Given that the compiler cannot make the assumptions I marked in the ass=
ert,=20
<br>can we have an attribute that lets the compiler know that the function=
=20
<br>promises not to modify it?
<br>
<br>I&#39;d wager that over 99% of uses of const a really const, but the co=
mpiler=20
<br>cannot optimise the code based on the constness. For example:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0std::string s =3D someF=
unction();
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (!s.empty()) {
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0doSomething(s)<wbr>;=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// an =
out-of-line function taking const ref
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0return <a href=3D"http://s.at" target=3D"_blank"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url=
?q\75http%3A%2F%2Fs.at\46sa\75D\46sntz\0751\46usg\75AFQjCNHjbVZbzoC6jn1e6_-=
j0YO3xlCjYA&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.googl=
e.com/url?q\75http%3A%2F%2Fs.at\46sa\75D\46sntz\0751\46usg\75AFQjCNHjbVZbzo=
C6jn1e6_-j0YO3xlCjYA&#39;;return true;">s.at</a>(0);=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<wbr>=C2=A0=C2=A0// &lt;--- HERE
<br>=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=A0return &#39;\0&#39;;
<br>
<br>The at() function is allowed to throw std::out_of_range. I&#39;d like t=
he compiler=20
<br>to optimise based on the fact that the string *isn&#39;t* empty in that=
 place=20
<br>because it wasn&#39;t empty before the out-of-line call.
<br>
<br>The [[pure]] attribute would do the trick, but it would not allow for f=
ine-
<br>grained control. It might be interesting to keep one argument immutable=
 but=20
<br>not others.
<br>
<br>Opinions?
<br>
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQ=
jCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.href=3D&=
#39;http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46snt=
z\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;">maciei=
ra.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\7=
5http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo5_JYG1Dowztw=
AHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google=
..com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo=
5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
 5358
<br><br></blockquote><div>How about just adding immutable as another qualif=
ier. That way casting away constness would be impossible and we&#39;ll fina=
lly have real consts.=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&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 />
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_56_61648598.1449779302049--
------=_Part_55_768081327.1449779302049--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 10 Dec 2015 13:09:42 -0800
Raw View
On Thursday 10 December 2015 12:28:21 tsvetan.dimitrov76@gmail.com wrote:
> How about just adding immutable as another qualifier. That way casting
> away constness would be impossible and we'll finally have real consts.

We could add a proper qualifier, but in this case an attribute suffices like
[[pure]] does. I don't mind either way, just so long as we can convey that no
bad const_cast'ing happens.

Another thing I wonder: can we do the same transitively for pointed data? You
may know that Qt uses d-pointers (private implementation) for almost all data.
The current QString implementation, for example, stores the size indirectly,
so it could modify the size even in a const function, without const_cast.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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: tsvetan.dimitrov76@gmail.com
Date: Thu, 10 Dec 2015 13:50:58 -0800 (PST)
Raw View
------=_Part_1217_1329685913.1449784258574
Content-Type: multipart/alternative;
 boundary="----=_Part_1218_47782252.1449784258575"

------=_Part_1218_47782252.1449784258575
Content-Type: text/plain; charset=UTF-8



On Thursday, December 10, 2015 at 11:10:22 PM UTC+2, Thiago Macieira wrote:
>
> On Thursday 10 December 2015 12:28:21 tsvetan.d...@gmail.com <javascript:>
> wrote:
> > How about just adding immutable as another qualifier. That way casting
> > away constness would be impossible and we'll finally have real consts.
>
> We could add a proper qualifier, but in this case an attribute suffices
> like
> [[pure]] does. I don't mind either way, just so long as we can convey that
> no
> bad const_cast'ing happens.
>
> Another thing I wonder: can we do the same transitively for pointed data?
> You
> may know that Qt uses d-pointers (private implementation) for almost all
> data.
> The current QString implementation, for example, stores the size
> indirectly,
> so it could modify the size even in a const function, without const_cast.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
> Transitivity is exactly the reason i suggested a qualifier instead of
attribute. Should work exactly as const works now with the only difference
that it can't be casted away and of course mutable immutable woulnd't make
any sense :). The downside would be an explosion of overloads.

--

---
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_1218_47782252.1449784258575
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Thursday, December 10, 2015 at 11:10:22 PM UTC+2, Thiago Macieir=
a wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Thursday 10 Decembe=
r 2015 12:28:21 <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"VcY6AOp6CwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;java=
script:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;">tsvetan.d...@gmail.com</a> wrote:
<br>&gt; How about just adding immutable as another qualifier. That way cas=
ting=20
<br>&gt; away constness would be impossible and we&#39;ll finally have real=
 consts.=20
<br>
<br>We could add a proper qualifier, but in this case an attribute suffices=
 like=20
<br>[[pure]] does. I don&#39;t mind either way, just so long as we can conv=
ey that no=20
<br>bad const_cast&#39;ing happens.
<br>
<br>Another thing I wonder: can we do the same transitively for pointed dat=
a? You=20
<br>may know that Qt uses d-pointers (private implementation) for almost al=
l data.=20
<br>The current QString implementation, for example, stores the size indire=
ctly,=20
<br>so it could modify the size even in a const function, without const_cas=
t.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQ=
jCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.href=3D&=
#39;http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46snt=
z\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;">maciei=
ra.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\7=
5http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo5_JYG1Dowztw=
AHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google=
..com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo=
5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
 5358
<br>
<br></blockquote><div>Transitivity is exactly the reason i suggested a qual=
ifier instead of attribute. Should work exactly as const works now with the=
 only difference that it can&#39;t be casted away and of course mutable imm=
utable woulnd&#39;t make any sense :). The downside would be an explosion o=
f overloads.</div>

<p></p>

-- <br />
<br />
--- <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 />
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_1218_47782252.1449784258575--
------=_Part_1217_1329685913.1449784258574--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 10 Dec 2015 16:56:46 -0500
Raw View
On 2015-12-10 16:09, Thiago Macieira wrote:
> Another thing I wonder: can we do the same transitively for pointed data? You
> may know that Qt uses d-pointers (private implementation) for almost all data.
> The current QString implementation, for example, stores the size indirectly,
> so it could modify the size even in a const function, without const_cast.

(Does d_func() const not return a const pointer? In qtExtensions, it
does...)

One possible solution to that - at least, that specific use case - is to
use a const-propagating pointer (i.e. so that the compiler knows that a
const method doesn't have access to a non-const FooPrivate*).

That said, how many const methods *aren't* actually [[pure]]? (Things
like mutable caches are the only things I can think of offhand where I'd
"expect" a const method to *not* be pure...)

--
Matthew

--

---
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: tsvetan.dimitrov76@gmail.com
Date: Thu, 10 Dec 2015 14:13:41 -0800 (PST)
Raw View
------=_Part_1091_864906346.1449785621867
Content-Type: multipart/alternative;
 boundary="----=_Part_1092_906112877.1449785621868"

------=_Part_1092_906112877.1449785621868
Content-Type: text/plain; charset=UTF-8



On Thursday, December 10, 2015 at 11:57:11 PM UTC+2, Matthew Woehlke wrote:
>
> On 2015-12-10 16:09, Thiago Macieira wrote:
> > Another thing I wonder: can we do the same transitively for pointed
> data? You
> > may know that Qt uses d-pointers (private implementation) for almost all
> data.
> > The current QString implementation, for example, stores the size
> indirectly,
> > so it could modify the size even in a const function, without
> const_cast.
>
> (Does d_func() const not return a const pointer? In qtExtensions, it
> does...)
>
> One possible solution to that - at least, that specific use case - is to
> use a const-propagating pointer (i.e. so that the compiler knows that a
> const method doesn't have access to a non-const FooPrivate*).
>
> That said, how many const methods *aren't* actually [[pure]]? (Things
> like mutable caches are the only things I can think of offhand where I'd
> "expect" a const method to *not* be pure...)
>
> --
> Matthew
>
Apart from mutable caches the other mutating effect I would expect from a
const member function would be taking a lock on a mutex.

--

---
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_1092_906112877.1449785621868
Content-Type: text/html; charset=UTF-8

<br><br>On Thursday, December 10, 2015 at 11:57:11 PM UTC+2, Matthew Woehlke wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-12-10 16:09, Thiago Macieira wrote:
<br>&gt; Another thing I wonder: can we do the same transitively for pointed data? You
<br>&gt; may know that Qt uses d-pointers (private implementation) for almost all data.
<br>&gt; The current QString implementation, for example, stores the size indirectly,
<br>&gt; so it could modify the size even in a const function, without const_cast.
<br>
<br>(Does d_func() const not return a const pointer? In qtExtensions, it
<br>does...)
<br>
<br>One possible solution to that - at least, that specific use case - is to
<br>use a const-propagating pointer (i.e. so that the compiler knows that a
<br>const method doesn&#39;t have access to a non-const FooPrivate*).
<br>
<br>That said, how many const methods *aren&#39;t* actually [[pure]]? (Things
<br>like mutable caches are the only things I can think of offhand where I&#39;d
<br>&quot;expect&quot; a const method to *not* be pure...)
<br>
<br>--
<br>Matthew
<br></blockquote><div>Apart from mutable caches the other mutating effect I would expect from a const member function would be taking a lock on a mutex.</div>

<p></p>

-- <br />
<br />
--- <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 email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_1092_906112877.1449785621868--
------=_Part_1091_864906346.1449785621867--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 10 Dec 2015 23:25:16 +0100
Raw View
This is a multi-part message in MIME format.
--------------010705090002000202060809
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 10/12/2015 22:56, Matthew Woehlke a =C3=A9crit :
> On 2015-12-10 16:09, Thiago Macieira wrote:
>> Another thing I wonder: can we do the same transitively for pointed data=
? You
>> may know that Qt uses d-pointers (private implementation) for almost all=
 data.
>> The current QString implementation, for example, stores the size indirec=
tly,
>> so it could modify the size even in a const function, without const_cast=
..
> (Does d_func() const not return a const pointer? In qtExtensions, it
> does...)
>
> One possible solution to that - at least, that specific use case - is to
> use a const-propagating pointer (i.e. so that the compiler knows that a
> const method doesn't have access to a non-const FooPrivate*).
>
> That said, how many const methods *aren't* actually [[pure]]? (Things
> like mutable caches are the only things I can think of offhand where I'd
> "expect" a const method to *not* be pure...)
>
logging?

Vicente

--=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/.

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 10/12/2015 22:56, Matthew Woehlke a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote cite=3D"mid:n4cseu$q9c$1@ger.gmane.org" type=3D"cite">
      <pre wrap=3D"">On 2015-12-10 16:09, Thiago Macieira wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">Another thing I wonder: can we do the same transitiv=
ely for pointed data? You=20
may know that Qt uses d-pointers (private implementation) for almost all da=
ta.=20
The current QString implementation, for example, stores the size indirectly=
,=20
so it could modify the size even in a const function, without const_cast.
</pre>
      </blockquote>
      <pre wrap=3D"">
(Does d_func() const not return a const pointer? In qtExtensions, it
does...)

One possible solution to that - at least, that specific use case - is to
use a const-propagating pointer (i.e. so that the compiler knows that a
const method doesn't have access to a non-const FooPrivate*).

That said, how many const methods *aren't* actually [[pure]]? (Things
like mutable caches are the only things I can think of offhand where I'd
"expect" a const method to *not* be pure...)

</pre>
    </blockquote>
    <font size=3D"+1">logging?<br>
      <br>
      Vicente<br>
    </font>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <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 />
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 />

--------------010705090002000202060809--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 10 Dec 2015 16:29:09 -0800
Raw View
On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
> On 2015-12-10 16:09, Thiago Macieira wrote:
> > Another thing I wonder: can we do the same transitively for pointed data?
> > You may know that Qt uses d-pointers (private implementation) for almost
> > all data. The current QString implementation, for example, stores the
> > size indirectly, so it could modify the size even in a const function,
> > without const_cast.
> (Does d_func() const not return a const pointer? In qtExtensions, it
> does...)

It does but that's irrelevant. You don't have to call it, you can access the
d_ptr member directly.

> One possible solution to that - at least, that specific use case - is to
> use a const-propagating pointer (i.e. so that the compiler knows that a
> const method doesn't have access to a non-const FooPrivate*).

Are you suggesting a new type of pointer primitive, with a new keyword?

struct MyClass
{
 same_const MyClassPrivate *d;
 void f() const;
};

Or are you suggesting a smart pointer class? A smart pointer class isn't
enough if the inner member is accessible.

> That said, how many const methods *aren't* actually [[pure]]? (Things
> like mutable caches are the only things I can think of offhand where I'd
> "expect" a const method to *not* be pure...)

That's what I said: I expect 99% of const to be "really const" and a great
deal of them to be pure. But we can't change the rules now...

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 11 Dec 2015 10:39:36 -0500
Raw View
On 2015-12-10 19:29, Thiago Macieira wrote:
> On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
>> On 2015-12-10 16:09, Thiago Macieira wrote:
>>> Another thing I wonder: can we do the same transitively for pointed data?
>>> You may know that Qt uses d-pointers (private implementation) for almost
>>> all data. The current QString implementation, for example, stores the
>>> size indirectly, so it could modify the size even in a const function,
>>> without const_cast.
>> (Does d_func() const not return a const pointer? In qtExtensions, it
>> does...)
>
> It does but that's irrelevant. You don't have to call it, you can access the
> d_ptr member directly.

Right... was just wondering. Since AFAIK it's convention in Qt to never
access d_ptr directly, this protection exists *in practice*, but not in
a way that the compiler can prove. (Which leads to my next point.)

>> One possible solution to that - at least, that specific use case - is to
>> use a const-propagating pointer (i.e. so that the compiler knows that a
>> const method doesn't have access to a non-const FooPrivate*).
>
> Are you suggesting a new type of pointer primitive, with a new keyword?
>
> struct MyClass
> {
>  same_const MyClassPrivate *d;
>  void f() const;
> };
>
> Or are you suggesting a smart pointer class? A smart pointer class isn't
> enough if the inner member is accessible.

It wouldn't be (directly). There would be only a public method that
returns the pointer *as const*. (We might still need a way to mark that
we'll actually honor the const, e.g. something that says 'no const_cast
will be used in this function'.)

>> That said, how many const methods *aren't* actually [[pure]]? (Things
>> like mutable caches are the only things I can think of offhand where I'd
>> "expect" a const method to *not* be pure...)
>
> That's what I said: I expect 99% of const to be "really const" and a great
> deal of them to be pure. But we can't change the rules now...

What we need is [[pure]]. I'm not suggesting to change existing
semantics. Rather, I'm trying to get an idea how often we really need
something besides the trivial case of [[pure]] (e.g. you suggested
marking individual parameters as 'we really, *really* promise not to
mutate these').

I see that [[pure]] was proposed (N3744), but it seems it's having
trouble getting accepted. (Maybe if OOE is accepted, that would
strengthen the case for [[pure]]?) It may be that the ability to specify
some form of partial purity is also helpful, but I suspect (and I
believe that, with your above statement, you are effectively agreeing)
that there would be quite a lot of benefit even from the trivial case.

(@Vicente, good point about logging. OTOH there are plenty of libraries
that don't have such extensive logging that would likely benefit from
[[pure]] quite a bit. Qt, for example :-).)

--
Matthew

--

---
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: Thiago Macieira <thiago@macieira.org>
Date: Fri, 11 Dec 2015 09:56:44 -0800
Raw View
On Friday 11 December 2015 10:39:36 Matthew Woehlke wrote:
> >> That said, how many const methods *aren't* actually [[pure]]? (Things
> >> like mutable caches are the only things I can think of offhand where I'd
> >> "expect" a const method to *not* be pure...)
> >
> > That's what I said: I expect 99% of const to be "really const" and a great
> > deal of them to be pure. But we can't change the rules now...
>
> What we need is [[pure]]. I'm not suggesting to change existing
> semantics. Rather, I'm trying to get an idea how often we really need
> something besides the trivial case of [[pure]] (e.g. you suggested
> marking individual parameters as 'we really, *really* promise not to
> mutate these').

I disagree that we need [[pure]]. There are many tasks that do not modify
their parameters and yet aren't pure. For example, locking a mutex isn't pure
because it's externally visible. We also had a discussion on whether
qGlobalQHashSeed was pure: it may read from the environment or even do I/O,
but only the first time it's called.

> (@Vicente, good point about logging. OTOH there are plenty of libraries
> that don't have such extensive logging that would likely benefit from
> [[pure]] quite a bit. Qt, for example :-).)

Logging is another example of non-pure behaviour and yet it won't modify the
parameters.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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: Fri, 11 Dec 2015 13:41:06 -0800 (PST)
Raw View
------=_Part_2811_1034930881.1449870066151
Content-Type: multipart/alternative;
 boundary="----=_Part_2812_786247320.1449870066152"

------=_Part_2812_786247320.1449870066152
Content-Type: text/plain; charset=UTF-8

On Friday, December 11, 2015 at 3:39:58 PM UTC, Matthew Woehlke wrote:
>
> On 2015-12-10 19:29, Thiago Macieira wrote:
> > On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
> >> On 2015-12-10 16:09, Thiago Macieira wrote:
> >>> Another thing I wonder: can we do the same transitively for pointed
> data?
> >>> You may know that Qt uses d-pointers (private implementation) for
> almost
> >>> all data. The current QString implementation, for example, stores the
> >>> size indirectly, so it could modify the size even in a const function,
> >>> without const_cast.
> >> (Does d_func() const not return a const pointer? In qtExtensions, it
> >> does...)
> >
> > It does but that's irrelevant. You don't have to call it, you can access
> the
> > d_ptr member directly.
>
> Right... was just wondering. Since AFAIK it's convention in Qt to never
> access d_ptr directly, this protection exists *in practice*, but not in
> a way that the compiler can prove. (Which leads to my next point.)
>
> >> One possible solution to that - at least, that specific use case - is
> to
> >> use a const-propagating pointer (i.e. so that the compiler knows that a
> >> const method doesn't have access to a non-const FooPrivate*).
> >
> > Are you suggesting a new type of pointer primitive, with a new keyword?
> >
> > struct MyClass
> > {
> >         same_const MyClassPrivate *d;
> >         void f() const;
> > };
> >
> > Or are you suggesting a smart pointer class? A smart pointer class isn't
> > enough if the inner member is accessible.
>
> It wouldn't be (directly). There would be only a public method that
> returns the pointer *as const*. (We might still need a way to mark that
> we'll actually honor the const, e.g. something that says 'no const_cast
> will be used in this function'.)
>
>
template<class T>
struct immutable_ptr {
     immutable_ptr(const T* x); // magic here: all previous references to
'x' are invalidated for as long as this is alive;

     struct immutable {
const T value;
                   operator const T&() const { return value; }
};



> >> That said, how many const methods *aren't* actually [[pure]]? (Things
> >> like mutable caches are the only things I can think of offhand where
> I'd
> >> "expect" a const method to *not* be pure...)
> >
> > That's what I said: I expect 99% of const to be "really const" and a
> great
> > deal of them to be pure. But we can't change the rules now...
>
> What we need is [[pure]]. I'm not suggesting to change existing
> semantics. Rather, I'm trying to get an idea how often we really need
> something besides the trivial case of [[pure]] (e.g. you suggested
> marking individual parameters as 'we really, *really* promise not to
> mutate these').
>
> I see that [[pure]] was proposed (N3744), but it seems it's having
> trouble getting accepted. (Maybe if OOE is accepted, that would
> strengthen the case for [[pure]]?) It may be that the ability to specify
> some form of partial purity is also helpful, but I suspect (and I
> believe that, with your above statement, you are effectively agreeing)
> that there would be quite a lot of benefit even from the trivial case.
>
> (@Vicente, good point about logging. OTOH there are plenty of libraries
> that don't have such extensive logging that would likely benefit from
> [[pure]] quite a bit. Qt, for example :-).)
>
> --
> Matthew
>
>

--

---
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_2812_786247320.1449870066152
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, December 11, 2015 at 3:39:58 PM UTC, Matthew Woehlke wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">On 2015-12-10 19:29, Thiago Macieir=
a wrote:
<br>&gt; On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
<br>&gt;&gt; On 2015-12-10 16:09, Thiago Macieira wrote:
<br>&gt;&gt;&gt; Another thing I wonder: can we do the same transitively fo=
r pointed data?
<br>&gt;&gt;&gt; You may know that Qt uses d-pointers (private implementati=
on) for almost
<br>&gt;&gt;&gt; all data. The current QString implementation, for example,=
 stores the
<br>&gt;&gt;&gt; size indirectly, so it could modify the size even in a con=
st function,
<br>&gt;&gt;&gt; without const_cast.
<br>&gt;&gt; (Does d_func() const not return a const pointer? In qtExtensio=
ns, it
<br>&gt;&gt; does...)
<br>&gt;=20
<br>&gt; It does but that&#39;s irrelevant. You don&#39;t have to call it, =
you can access the=20
<br>&gt; d_ptr member directly.
<br>
<br>Right... was just wondering. Since AFAIK it&#39;s convention in Qt to n=
ever
<br>access d_ptr directly, this protection exists *in practice*, but not in
<br>a way that the compiler can prove. (Which leads to my next point.)
<br>
<br>&gt;&gt; One possible solution to that - at least, that specific use ca=
se - is to
<br>&gt;&gt; use a const-propagating pointer (i.e. so that the compiler kno=
ws that a
<br>&gt;&gt; const method doesn&#39;t have access to a non-const FooPrivate=
*).
<br>&gt;=20
<br>&gt; Are you suggesting a new type of pointer primitive, with a new key=
word?
<br>&gt;=20
<br>&gt; struct MyClass
<br>&gt; {
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0same_const MyClass=
Private *d;
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0void f() const;
<br>&gt; };
<br>&gt;=20
<br>&gt; Or are you suggesting a smart pointer class? A smart pointer class=
 isn&#39;t=20
<br>&gt; enough if the inner member is accessible.
<br>
<br>It wouldn&#39;t be (directly). There would be only a public method that
<br>returns the pointer *as const*. (We might still need a way to mark that
<br>we&#39;ll actually honor the const, e.g. something that says &#39;no co=
nst_cast
<br>will be used in this function&#39;.)
<br>
<br></blockquote><div><br>template&lt;class T&gt;<br>struct immutable_ptr {=
<br>=C2=A0=C2=A0=C2=A0=C2=A0 immutable_ptr(const T* x); // magic here: all =
previous references to &#39;x&#39; are invalidated for as long as this is a=
live;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0 struct immutable { <br>const T value;=
 <br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 operator const T&amp;() const { ret=
urn value; }<br>};<br><br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;">&gt;&gt; That said, how many const methods *aren&#39;t* actually [[=
pure]]? (Things
<br>&gt;&gt; like mutable caches are the only things I can think of offhand=
 where I&#39;d
<br>&gt;&gt; &quot;expect&quot; a const method to *not* be pure...)
<br>&gt;=20
<br>&gt; That&#39;s what I said: I expect 99% of const to be &quot;really c=
onst&quot; and a great=20
<br>&gt; deal of them to be pure. But we can&#39;t change the rules now...
<br>
<br>What we need is [[pure]]. I&#39;m not suggesting to change existing
<br>semantics. Rather, I&#39;m trying to get an idea how often we really ne=
ed
<br>something besides the trivial case of [[pure]] (e.g. you suggested
<br>marking individual parameters as &#39;we really, *really* promise not t=
o
<br>mutate these&#39;).
<br>
<br>I see that [[pure]] was proposed (N3744), but it seems it&#39;s having
<br>trouble getting accepted. (Maybe if OOE is accepted, that would
<br>strengthen the case for [[pure]]?) It may be that the ability to specif=
y
<br>some form of partial purity is also helpful, but I suspect (and I
<br>believe that, with your above statement, you are effectively agreeing)
<br>that there would be quite a lot of benefit even from the trivial case.
<br>
<br>(@Vicente, good point about logging. OTOH there are plenty of libraries
<br>that don&#39;t have such extensive logging that would likely benefit fr=
om
<br>[[pure]] quite a bit. Qt, for example :-).)
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote>

<p></p>

-- <br />
<br />
--- <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 />
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_2812_786247320.1449870066152--
------=_Part_2811_1034930881.1449870066151--

.


Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Fri, 11 Dec 2015 13:52:50 -0800 (PST)
Raw View
------=_Part_2665_1687846986.1449870770789
Content-Type: multipart/alternative;
 boundary="----=_Part_2666_1664163193.1449870770789"

------=_Part_2666_1664163193.1449870770789
Content-Type: text/plain; charset=UTF-8

On Friday, December 11, 2015 at 3:39:58 PM UTC, Matthew Woehlke wrote:
>
> On 2015-12-10 19:29, Thiago Macieira wrote:
> > On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
> >> On 2015-12-10 16:09, Thiago Macieira wrote:
> >>> Another thing I wonder: can we do the same transitively for pointed
> data?
> >>> You may know that Qt uses d-pointers (private implementation) for
> almost
> >>> all data. The current QString implementation, for example, stores the
> >>> size indirectly, so it could modify the size even in a const function,
> >>> without const_cast.
> >> (Does d_func() const not return a const pointer? In qtExtensions, it
> >> does...)
> >
> > It does but that's irrelevant. You don't have to call it, you can access
> the
> > d_ptr member directly.
>
> Right... was just wondering. Since AFAIK it's convention in Qt to never
> access d_ptr directly, this protection exists *in practice*, but not in
> a way that the compiler can prove. (Which leads to my next point.)
>
> >> One possible solution to that - at least, that specific use case - is
> to
> >> use a const-propagating pointer (i.e. so that the compiler knows that a
> >> const method doesn't have access to a non-const FooPrivate*).
> >
> > Are you suggesting a new type of pointer primitive, with a new keyword?
> >
> > struct MyClass
> > {
> >         same_const MyClassPrivate *d;
> >         void f() const;
> > };
> >
> > Or are you suggesting a smart pointer class? A smart pointer class isn't
> > enough if the inner member is accessible.
>
> It wouldn't be (directly). There would be only a public method that
> returns the pointer *as const*. (We might still need a way to mark that
> we'll actually honor the const, e.g. something that says 'no const_cast
> will be used in this function'.)
>
>
My take on a deep const pointer:

template<class T>
struct immutable_ptr {
     immutable_ptr(const T* x); // magic here: all previous references to
'x' are invalidated for as long as this is alive;

     struct immutable {
                   const T value;
                   operator const T&() const { return value; }
                   const T& operator->() const { return value; }
      }

      immutable const& operator *() const;
      immutable const& operator->() const; // more magic
private:
};

The semantics of the constructor are such that the '*x' parameter is
destroyed (not deleted) and an immutable_ptr<T>::immutable is created whose
value is equivalent to the previously destroyed object, possibly at the
same memory location. When the immutable_ptr is destroyed, the original
object is reinstated.

When immutable_ptr operators * and -> an immutable reference is returned.
As the T 'value' object is declared const as part of the type itself, the
compiler can assume it will not be mutated by any call.

-- 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_2666_1664163193.1449870770789
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, December 11, 2015 at 3:39:58 PM UTC, Matthew Woehlke wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">On 2015-12-10 19:29, Thiago Macieir=
a wrote:
<br>&gt; On Thursday 10 December 2015 16:56:46 Matthew Woehlke wrote:
<br>&gt;&gt; On 2015-12-10 16:09, Thiago Macieira wrote:
<br>&gt;&gt;&gt; Another thing I wonder: can we do the same transitively fo=
r pointed data?
<br>&gt;&gt;&gt; You may know that Qt uses d-pointers (private implementati=
on) for almost
<br>&gt;&gt;&gt; all data. The current QString implementation, for example,=
 stores the
<br>&gt;&gt;&gt; size indirectly, so it could modify the size even in a con=
st function,
<br>&gt;&gt;&gt; without const_cast.
<br>&gt;&gt; (Does d_func() const not return a const pointer? In qtExtensio=
ns, it
<br>&gt;&gt; does...)
<br>&gt;=20
<br>&gt; It does but that&#39;s irrelevant. You don&#39;t have to call it, =
you can access the=20
<br>&gt; d_ptr member directly.
<br>
<br>Right... was just wondering. Since AFAIK it&#39;s convention in Qt to n=
ever
<br>access d_ptr directly, this protection exists *in practice*, but not in
<br>a way that the compiler can prove. (Which leads to my next point.)
<br>
<br>&gt;&gt; One possible solution to that - at least, that specific use ca=
se - is to
<br>&gt;&gt; use a const-propagating pointer (i.e. so that the compiler kno=
ws that a
<br>&gt;&gt; const method doesn&#39;t have access to a non-const FooPrivate=
*).
<br>&gt;=20
<br>&gt; Are you suggesting a new type of pointer primitive, with a new key=
word?
<br>&gt;=20
<br>&gt; struct MyClass
<br>&gt; {
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0same_const MyClass=
Private *d;
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0void f() const;
<br>&gt; };
<br>&gt;=20
<br>&gt; Or are you suggesting a smart pointer class? A smart pointer class=
 isn&#39;t=20
<br>&gt; enough if the inner member is accessible.
<br>
<br>It wouldn&#39;t be (directly). There would be only a public method that
<br>returns the pointer *as const*. (We might still need a way to mark that
<br>we&#39;ll actually honor the const, e.g. something that says &#39;no co=
nst_cast
<br>will be used in this function&#39;.)
<br>
<br></blockquote><div><br>My take on a deep const pointer:<br><br>template&=
lt;class T&gt;<br>struct immutable_ptr {<br>=C2=A0=C2=A0=C2=A0=C2=A0 immuta=
ble_ptr(const T* x); // magic here: all previous references to &#39;x&#39; =
are invalidated for as long as this is alive;<br><br>=C2=A0=C2=A0=C2=A0=C2=
=A0 struct immutable { <br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const T value;=
 <br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 operator const T&amp;() const { ret=
urn value; }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const T&amp; operator-&=
gt;() const { return value; }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br><br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 immutable const&amp; operator *() const;<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 immutable const&amp; operator-&gt;() const; =
// more magic<br>private:<br>};<br>=C2=A0<br>The semantics of the construct=
or are such that the &#39;*x&#39; parameter is destroyed (not deleted) and =
an immutable_ptr&lt;T&gt;::immutable is created whose value is equivalent t=
o the previously destroyed object, possibly at the same memory location. Wh=
en the immutable_ptr is destroyed, the original object is reinstated.<br><b=
r>When immutable_ptr operators * and -&gt; an immutable reference is return=
ed. As the T &#39;value&#39; object is declared const as part of the type i=
tself, the compiler can assume it will not be mutated by any call.<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&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 />
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_2666_1664163193.1449870770789--
------=_Part_2665_1687846986.1449870770789--

.