www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - cast(!const) proposal

reply "Janice Caron" <caron800 googlemail.com> writes:
When I mentioned this on another thread, I got misunderstood, so I'm
going to try again, only this time being very, very clear, so
hopefully it will all make sense this time.

I propose that it shall be a compile-time error to cast away constness
or invariance with the existing syntax.

For example

const int n = 42;
auto p = &n;
auto q = cast(int *)p; /* Currently compiles. I propose that it should
be a compile error */

Since D is a nuts-and-bolts language, and Walter doesn't actually want
to prevent you from doing stupid things, there must be a way of
getting round that restriction. The intent is not to /prevent/ you
from being stupid - I mean, doing low level nuts-and-bolts things -
it's to require you to use a different syntax, so that you damn well
can't do it by accident. The syntax that I suggest for this is:

auto q = cast(!const)p;

This would allow the existing cast syntax to be made const-safe, and
is also consistent with the exisiting cast(const) syntax.
Sep 09 2007
next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
I think this is good idea. It will help to find this class of bugs, 
which although one shouldn't make, if it is there it will be sneaky one.

Note that if you want to cast the underlying types too it will be quite 
ugly:

auto q = cast(long*)cast(!const)p;

You might agree that the syntax of !const can be something different, it 
doesn't really matter as long as it achieves the same thing: catching 
casting away const by accident. I personally don't care if it's 
foobar_cast or whatever, if it's recognizable that's fine.

It will also allow you to grep your or other peoples source for this 
kind of cast, which is currently not possible at all in D, but is in C++.
Sep 09 2007
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Lutger wrote:
 I think this is good idea. It will help to find this class of bugs, 
 which although one shouldn't make, if it is there it will be sneaky one.
 
 Note that if you want to cast the underlying types too it will be quite 
 ugly:
 
 auto q = cast(long*)cast(!const)p;
 
 You might agree that the syntax of !const can be something different, it 
 doesn't really matter as long as it achieves the same thing: catching 
 casting away const by accident. I personally don't care if it's 
 foobar_cast or whatever, if it's recognizable that's fine.
 
 It will also allow you to grep your or other peoples source for this 
 kind of cast, which is currently not possible at all in D, but is in C++.
 
 
My earlier proposal was: cast(break const) for essentially the same thing. But we really need something for this, whatever the syntax.
Sep 09 2007
parent Jason House <jason.james.house gmail.com> writes:
Don Clugston wrote:
 My earlier proposal was:
 cast(break const)
 for essentially the same thing. But we really need something for this, 
 whatever the syntax.
IIRC, that alternative was the most popular in the original thread. Personally, I won't like the const framework until there is a safe way of converting to/from the various types of constness. I have ideas on the topic, but I don't know if my issues are considered a problem or not.
Sep 10 2007
prev sibling next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
 It will also allow you to grep your or other peoples source for this
 kind of cast, which is currently not possible at all in D, but is in C++.
Actually, it's not possible is C++, because even though you can grep for const_cast, you can't grep for the old-fashioned C way of casting, and that's still legal in C++. D would automatically become the winner.
Sep 09 2007
parent James Dennett <jdennett acm.org> writes:
Janice Caron wrote:
 It will also allow you to grep your or other peoples source for this
 kind of cast, which is currently not possible at all in D, but is in C++.
Actually, it's not possible is C++, because even though you can grep for const_cast, you can't grep for the old-fashioned C way of casting, and that's still legal in C++.
But can be disallowed by coding conventions, and reported by tools; working in a sensible subset that bans C-style casts, and grepping is effective. (I'm oversimplifying unfortunately, as C++ also has functional style casts, which have the same semantics as C-style casts.)
 D would automatically become the winner.
;) -- James
Sep 09 2007
prev sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Lutger wrote:
 I think this is good idea. It will help to find this class of bugs, 
 which although one shouldn't make, if it is there it will be sneaky one.
 
 Note that if you want to cast the underlying types too it will be quite 
 ugly:
 
 auto q = cast(long*)cast(!const)p;
What's wrong with: auto q = cast(!const long*)p; as the almost opposite of: auto q = cast(const long*)p; Regan
Sep 10 2007
parent "Janice Caron" <caron800 googlemail.com> writes:
Content-Disposition: inline

Yeah, that works too.
Sep 10 2007
prev sibling next sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Janice Caron wrote:
 When I mentioned this on another thread, I got misunderstood, so I'm
 going to try again, only this time being very, very clear, so
 hopefully it will all make sense this time.
 
 I propose that it shall be a compile-time error to cast away constness
 or invariance with the existing syntax.
 
 For example
 
 const int n = 42;
 auto p = &n;
 auto q = cast(int *)p; /* Currently compiles. I propose that it should
 be a compile error */
 
 Since D is a nuts-and-bolts language, and Walter doesn't actually want
 to prevent you from doing stupid things, there must be a way of
 getting round that restriction. The intent is not to /prevent/ you
 from being stupid - I mean, doing low level nuts-and-bolts things -
 it's to require you to use a different syntax, so that you damn well
 can't do it by accident. The syntax that I suggest for this is:
 
 auto q = cast(!const)p;
 
 This would allow the existing cast syntax to be made const-safe, and
 is also consistent with the exisiting cast(const) syntax.
This issue has been brought up before, and many of us also agree it is a problem: http://www.digitalmars.com/d/archives/digitalmars/D/D2.0_an_example_of_use-case_for_casting_invariant_away_54620.html I noted on that thread that "cast(!const)" can be made just as well using D's meta programming capabilites. A new syntax is not needed, although nonetheless, this construct should be on the standard library. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 10 2007
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
vote++
Sep 11 2007
parent reply "Janice Caron" <caron800 googlemail.com> writes:
While I think of it, casting from const pointer to int should also be
illegal without that same special syntax.

For example

const int n = 42;
auto p = &n;
auto k = cast(int)p; /* should be a compile error */

Do we have intptr_t in D?

Anyway, losing the constness by casting to int is cheating, so that
too should require the special syntax.
Sep 11 2007
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
 While I think of it, casting from const pointer to int should also be
 illegal without that same special syntax.

 For example

 const int n = 42;
 auto p = &n;
 auto k = cast(int)p; /* should be a compile error */

 Do we have intptr_t in D?

 Anyway, losing the constness by casting to int is cheating, so that
 too should require the special syntax.
I don't agree. You are getting into Java-style hide-all-pointers terminology here. If we are to have pointers, then I think we are going to have to agree that there will be ways to do *bad* things with them. I can think of other ways to circumvent your const rule about casting to int that will allow code to change const data without having to use the cast(!const). I don't think it will be possible to get around all these possibilities with compiler errors. My opinion is that any time you are casting away const, you should need the special cast(!const). If you are doing funky things to get around that rule, then you are on your own. patient: "doctor, it hurts when I do this!" doctor: "then don't do that." -Steve
Sep 11 2007
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 9/11/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 I don't agree.
Seems to me that you and I are actually in complete agreement. (Well, one of my replies starts with "But" - see below).
 If we are to have pointers, then I think we are going to
 have to agree that there will be ways to do *bad* things with them.
Of course.
  I can
 think of other ways to circumvent your const rule about casting to int that
 will allow code to change const data without having to use the cast(!const).
So can I. I even gave an example on another thread, with a working demo.
 I don't think it will be possible to get around all these possibilities with
 compiler errors.
But it *will* be possible to outlaw cast(T)x, wherever T has different const characteristics from typeof(x). As soon as the compiler sees that, it can insist on cast(!const)x or cast(!const T)x.
 My opinion is that any time you are casting away const, you should need the
 special cast(!const).
That's what I said.
 If you are doing funky things to get around that
 rule, then you are on your own.
I said that too. So fear not - I think we're on the same page here. :-)
Sep 11 2007
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
 On 9/11/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 I don't agree.
Seems to me that you and I are actually in complete agreement. (Well, one of my replies starts with "But" - see below).
Hm... in that case, I misunderstood this extra "pointer to int" specification, and I also don't understand why this even needs to be specified :) It seems redundant. I interpreted your post as you were trying to say if you have a mutable pointer to immutable data, you cannot cast the mutable pointer type into a mutable integer without doing a !const cast. That was where my disagreement was. Since the pointer is mutable, it should be perfectly legal to cast it into another compatible mutable type without a !const cast. yes/no? -Steve
Sep 11 2007
parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/11/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 I interpreted your post as you were trying to say if you have a mutable
 pointer to immutable data, you cannot cast the mutable pointer type into a
 mutable integer without doing a !const cast.
I was.
 That was where my disagreement was.
Oh. Right. Well then, I guess that /was/ a disagreement. But I've changed my mind now and I think you're right.
 Since the pointer is mutable, it should be perfectly legal to cast it
 into another compatible mutable type without a !const cast.
You can argue either way. My take was that, without a cast(!const), the only thing you should be allowed to convert a pointer-to-const into is another pointer-to-const. (You should be allowed to add constness, of course, but not to remove it). This isn't about catching tricksters, it's about preventing /accidents/. So if I type: auto n = cast(intptr_t) p; I thought it might be kinda nice if the compiler could "remind" me if p was a pointer-to-const, so that I didn't do it by accident. But on second thoughts, there's really no justification for insisting on a cast(!const) here, because const-correctness isn't necessarily being abused. Points to you on this one then. :-) Cheers
Sep 11 2007
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
 The syntax that I suggest for this is:

 auto q = cast(!const)p;
A crazy thought just occurred to me. If we are successful in lobbying for the mutable keyword, I think this could become: cast(mutable)p; looks a lot more straightforward than !const, especially when ! is used in templates. -Steve
Sep 12 2007
parent Derek Parnell <derek psych.ward> writes:
On Wed, 12 Sep 2007 14:17:44 -0400, Steven Schveighoffer wrote:

 "Janice Caron" wrote
 The syntax that I suggest for this is:

 auto q = cast(!const)p;
A crazy thought just occurred to me. If we are successful in lobbying for the mutable keyword, I think this could become: cast(mutable)p; looks a lot more straightforward than !const, especially when ! is used in templates.
Yes! That is just right, and thus will never see the light of day :-) -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Sep 12 2007