On Fri, 27 Jan 2012 08:05:24 -0500, Stewart Gordon <[email protected]>
wrote:
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);
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).
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.
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?
No, just busy (and a little lazy) :) I tested it now, and I see it
doesn't do the proper thing.
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.
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.
-Steve