Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 25, 2013 mutable constant? | ||||
---|---|---|---|---|
| ||||
I want to ask if this code should compile or if it's a bug, because I circumvent the const system: ---- import std.stdio; struct Point { int x, y; } Point*[] points; struct TplPoint(T) { public: Point _point; T x, y; const uint id; this(T x, T y) { this.x = x; this.y = y; points ~= &this._point; id = points.length - 1; } @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return cast(inout Point*) points[this.id]; } } void main() { const TplPoint!float my = TplPoint!float(42, 23); writeln(my._point, "::", &my._point); writeln(*my.ptr, "::", my.ptr); } ---- Or is the fact that it compiles ok and it's "only" unsafe? |
June 25, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Wed, 26 Jun 2013 00:07:38 +0200, Namespace <rswhite4@googlemail.com> wrote: > I want to ask if this code should compile or if it's a bug, because I circumvent the const system: > > ---- > import std.stdio; > > struct Point { > int x, y; > } > > Point*[] points; > > struct TplPoint(T) { > public: > Point _point; > > T x, y; > > const uint id; > > this(T x, T y) { > this.x = x; > this.y = y; > > points ~= &this._point; > > id = points.length - 1; > } > > @property > inout(Point)* ptr() inout { > points[this.id].x = cast(int) this.x; > points[this.id].y = cast(int) this.y; > > return cast(inout Point*) points[this.id]; > } > } > > void main() { > const TplPoint!float my = TplPoint!float(42, 23); > writeln(my._point, "::", &my._point); > writeln(*my.ptr, "::", my.ptr); > } > ---- > > Or is the fact that it compiles ok and it's "only" unsafe? This is perfectly fine. -- Simen |
June 25, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Wednesday, June 26, 2013 00:07:38 Namespace wrote:
> I want to ask if this code should compile or if it's a bug, because I circumvent the const system:
>
> ----
> import std.stdio;
>
> struct Point {
> int x, y;
> }
>
> Point*[] points;
>
> struct TplPoint(T) {
> public:
> Point _point;
>
> T x, y;
>
> const uint id;
>
> this(T x, T y) {
> this.x = x;
> this.y = y;
>
> points ~= &this._point;
>
> id = points.length - 1;
> }
>
> @property
> inout(Point)* ptr() inout {
> points[this.id].x = cast(int) this.x;
> points[this.id].y = cast(int) this.y;
>
> return cast(inout Point*) points[this.id];
> }
> }
>
> void main() {
> const TplPoint!float my = TplPoint!float(42, 23);
> writeln(my._point, "::", &my._point);
> writeln(*my.ptr, "::", my.ptr);
> }
> ----
>
> Or is the fact that it compiles ok and it's "only" unsafe?
I could certainly be missing something here, but I don't understand what about the code you're even concerned about. Where in here would you be breaking the type system? I don't see any place in here where you're mutating a const variable or anything like that. The worst thing I see about the code is that it won't compile on 64-bit machines thanks to
id = points.length - 1;
- Jonathan M Davis
|
June 25, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | If you change uint to size_t it works fine AFAIK. |
June 25, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Wednesday, June 26, 2013 00:52:58 Namespace wrote:
> If you change uint to size_t it works fine AFAIK.
Yes. It's easy enough to fix, but it _is_ arguably a bug in the code, and it's the only one that's obvious to me. I don't understand what about the code makes you think that it might be violating the type system.
- Jonathan M Davis
P.S. Please always quote at least a portion of the post that you're replying to. Clients frequently do not manage to thread posts correctly, and it's not always clear which post a post is replying to if it doesn't quote any of its parent. In this particular case, based on what you said, I expect that you were replying to me, but it's threaded in my client as being a responsed to Simen. Also, not all posters even use a threaded view. So, relying on threading to make it clear which post you're replying to is not a good idea.
|
June 25, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | With apologies, I have unrelated comments to make. On 06/25/2013 03:07 PM, Namespace wrote: > this(T x, T y) { > this.x = x; > this.y = y; > > points ~= &this._point; I have seen similar designs in the past where constructors had side-effects such as registering the object in a global state. (Exactly what the last line is doing above.) It has almost always been cause of trouble. It is better to register an object from the outside after constructing it. Sometimes I had attempted to remove seemingly unused objects only to be reminded by a comment that it should not be: // Do not remove! Registers itself in the points array auto p = Point(); > @property > inout(Point)* ptr() inout { > points[this.id].x = cast(int) this.x; > points[this.id].y = cast(int) this.y; That looks questionable as well: ptr() looks like an accessor but it makes changes to a global state. Ali |
June 26, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 25 June 2013 at 23:39:45 UTC, Ali Çehreli wrote:
> With apologies, I have unrelated comments to make.
>
> On 06/25/2013 03:07 PM, Namespace wrote:
>
> > this(T x, T y) {
> > this.x = x;
> > this.y = y;
> >
> > points ~= &this._point;
>
> I have seen similar designs in the past where constructors had side-effects such as registering the object in a global state. (Exactly what the last line is doing above.)
>
> It has almost always been cause of trouble. It is better to register an object from the outside after constructing it.
>
> Sometimes I had attempted to remove seemingly unused objects only to be reminded by a comment that it should not be:
>
> // Do not remove! Registers itself in the points array
> auto p = Point();
>
> > @property
> > inout(Point)* ptr() inout {
> > points[this.id].x = cast(int) this.x;
> > points[this.id].y = cast(int) this.y;
>
> That looks questionable as well: ptr() looks like an accessor but it makes changes to a global state.
>
> Ali
This is no real code. Just a test example to check. ;)
|
June 26, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Wednesday, 26 June 2013 at 07:35:08 UTC, Namespace wrote: > On Tuesday, 25 June 2013 at 23:39:45 UTC, Ali Çehreli wrote: >> With apologies, I have unrelated comments to make. >> >> On 06/25/2013 03:07 PM, Namespace wrote: >> >> > this(T x, T y) { >> > this.x = x; >> > this.y = y; >> > >> > points ~= &this._point; >> >> I have seen similar designs in the past where constructors had side-effects such as registering the object in a global state. (Exactly what the last line is doing above.) >> >> It has almost always been cause of trouble. It is better to register an object from the outside after constructing it. >> >> Sometimes I had attempted to remove seemingly unused objects only to be reminded by a comment that it should not be: >> >> // Do not remove! Registers itself in the points array >> auto p = Point(); >> >> > @property >> > inout(Point)* ptr() inout { >> > points[this.id].x = cast(int) this.x; >> > points[this.id].y = cast(int) this.y; >> >> That looks questionable as well: ptr() looks like an accessor but it makes changes to a global state. >> >> Ali > > This is no real code. Just a test example to check. ;) It seems safe, however, your example seems to show how to indeed break the type system... without a cast (!): @property Point* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return points[this.id]; } void main() { immutable TplPoint!float my = TplPoint!float(42, 23); Point* p = my.ptr; //Oops! mutable point! } Disturbing... > this(T x, T y) { > this.x = x; > this.y = y; > > points ~= &this._point; I'd careful with this, you can easily end up with pointers to destroyed temporaries... |
June 26, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, June 26, 2013 13:16:16 monarch_dodra wrote:
> It seems safe, however, your example seems to show how to indeed break the type system... without a cast (!):
>
> @property
> Point* ptr() inout {
> points[this.id].x = cast(int) this.x;
> points[this.id].y = cast(int) this.y;
>
> return points[this.id];
> }
>
>
> void main() {
> immutable TplPoint!float my = TplPoint!float(42, 23);
> Point* p = my.ptr; //Oops! mutable point!
> }
>
> Disturbing...
It doesn't break anything. It just shows the need for pure.
- Jonathan M Davis
|
June 26, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis wrote:
>
> It doesn't break anything. It just shows the need for pure.
>
> - Jonathan M Davis
OOhhhh.... I just got it :(
nevermind then...
|
Copyright © 1999-2021 by the D Language Foundation