digitalmars.D.learn - inout constructor?
- bearophile (8/8) Jan 25 2012 In this bug report I've seen an inout struct constructor:
- Steven Schveighoffer (22/28) Jan 26 2012 I would say possibly something like this:
- Stewart Gordon (26/36) Jan 27 2012 To actually get an immutable object (trying it on DMD 2.057), you need t...
- Steven Schveighoffer (30/72) Jan 27 2012 Right, the above is a proposed behavior for inout constructors. The poi...
In this bug report I've seen an inout struct constructor: http://d.puremagic.com/issues/show_bug.cgi?id=7369 struct TestStruct { this(int data) inout {} } Do you know what's the usage of this? Bye and thank you, bearophile
Jan 25 2012
On Wed, 25 Jan 2012 23:08:01 -0500, bearophile <bearophileHUGS lycos.com> wrote:In this bug report I've seen an inout struct constructor: http://d.puremagic.com/issues/show_bug.cgi?id=7369 struct TestStruct { this(int data) inout {} } Do you know what's the usage of this?I would say possibly something like this: struct TestStruct { int *data; this(inout(int)* d) inout { this.data = d; } // allowed just like a const ctor can set its members once. } int xm; const(int) xc; immutable(int) xi; auto tsm = TestStruct(&xm); auto tsc = TestStruct(&xc); auto tsi = TestStruct(&xi); writeln(typeof(tsm).stringof); // TestStruct writeln(typeof(tsc).stringof); // const(TestStruct) writeln(typeof(tsi).stringof); // immutable(TestStruct) I'll note that I don't think this is currently supported, but I could see how it would be useful. However, in that bug report, there are no inout parameters besides the 'this' pointer, so I'm not sure what the purpose would be there. -Steve
Jan 26 2012
On 26/01/2012 15:27, Steven Schveighoffer wrote: <snip>auto tsm = TestStruct(&xm); auto tsc = TestStruct(&xc); auto tsi = TestStruct(&xi); writeln(typeof(tsm).stringof); // TestStruct writeln(typeof(tsc).stringof); // const(TestStruct) writeln(typeof(tsi).stringof); // immutable(TestStruct)To actually get an immutable object (trying it on DMD 2.057), you need to use auto tsi = immutable(TestStruct)(&xi); I think the reason is: Think of a constructor as a method that always returns this. The implicit this pointer points to a space that has been allocated in advance to hold the constructed object. this(inout(int)* d) inout { this.data = d; } auto ts = TestStruct(&xi); is essentially inout(TestStruct) ctor(inout(int)* d) inout { this.data = d; return this; } TestStruct temp; auto ts = temp.ctor(&xi); The implicit this pointer is a TestStruct* (mutable), but &xi is an immutable(int*). The only way to match both is to match the inout as const, so a const is what it returns. But it doesn't work properly with a class instead of a struct at the moment.I'll note that I don't think this is currently supported, but I could see how it would be useful.You away from your usual testing station?However, in that bug report, there are no inout parameters besides the 'this' pointer, so I'm not sure what the purpose would be there.The purpose of it in the example is to be a minimal testcase for the bug. But in the general case, the purpose is to enable a mutable, const or immutable object to be constructed to wrap existing data that has the same constancy. Stewart.
Jan 27 2012
On Fri, 27 Jan 2012 08:05:24 -0500, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 26/01/2012 15:27, Steven Schveighoffer wrote: <snip>Right, the above is a proposed behavior for inout constructors. The point is that an inout constructor could be useful for replacing three constructors, each of which would have to be marked const, immutable, or mutable (no marks).auto tsm = TestStruct(&xm); auto tsc = TestStruct(&xc); auto tsi = TestStruct(&xi); writeln(typeof(tsm).stringof); // TestStruct writeln(typeof(tsc).stringof); // const(TestStruct) writeln(typeof(tsi).stringof); // immutable(TestStruct)To actually get an immutable object (trying it on DMD 2.057), you need to use auto tsi = immutable(TestStruct)(&xi);I think the reason is: Think of a constructor as a method that always returns this. The implicit this pointer points to a space that has been allocated in advance to hold the constructed object. this(inout(int)* d) inout { this.data = d; } auto ts = TestStruct(&xi); is essentially inout(TestStruct) ctor(inout(int)* d) inout { this.data = d; return this; } TestStruct temp; auto ts = temp.ctor(&xi);This is not true. A constructor used on an initializer is special in that the constructed struct does not logically exist before the construction. This may be the way it currently works in the compiler, but that is a bug. Essentially, this: this(inout(int)* d) inout { this.data = d; } should reduce to this: this( int * d) {this.data = d;} this( const(int)* d) const {this.data = d;} this(immutable(int)* d) immutable {this.data = d;} Which already works today (the three constructors I mean).The implicit this pointer is a TestStruct* (mutable), but &xi is an immutable(int*). The only way to match both is to match the inout as const, so a const is what it returns.No, the implicit this pointer's constancy is decided by the attribute on the constructor. In the case of constructors, the const or immutable attribute becomes the attribute of the return value. Inside the constructor, special rules are used. For example, you can assign to member variables once, even in a const or immutable ctor.But it doesn't work properly with a class instead of a struct at the moment.I just tested, and it actually compiles for a struct, but doesn't work properly. Instead I get const for both immutable and const.No, just busy (and a little lazy) :) I tested it now, and I see it doesn't do the proper thing.I'll note that I don't think this is currently supported, but I could see how it would be useful.You away from your usual testing station?Yes, I agree. But you need to put inout on the parameter in order for it to properly reach the result (the constructed object) I suspect the special case of the ctor is not treated correctly. I'll file a bug. -SteveHowever, in that bug report, there are no inout parameters besides the 'this' pointer, so I'm not sure what the purpose would be there.The purpose of it in the example is to be a minimal testcase for the bug. But in the general case, the purpose is to enable a mutable, const or immutable object to be constructed to wrap existing data that has the same constancy.
Jan 27 2012