inout constructor?

Steven Schveighoffer schveiguy at yahoo.com
Fri Jan 27 06:38:31 PST 2012


On Fri, 27 Jan 2012 08:05:24 -0500, Stewart Gordon <smjg_1998 at yahoo.com>  
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


More information about the Digitalmars-d-learn mailing list