using .init reliably

Steven Schveighoffer schveiguy at yahoo.com
Mon Oct 30 15:03:25 UTC 2017


On 10/30/17 6:59 AM, Alex wrote:
> Sorry for dig out this posting, but this one is more recent, than
> 
> http://forum.dlang.org/thread/k15of5$22ub$1@digitalmars.com?page=1
> 
> and my question is just beyond the two:
> 
> I'm with you, regarding that the standard init property should not be 
> overridden. But how about to override it with a custom init function, 
> which has a different interface?
> 
> An example:
> 
> /// --- code --- ///
> void main()
> {
>      int first = 5;
>      //auto s0 = S.init; // this line (4) yields an error:
>          // function app.S.init (int fParam) is not callable using 
> argument types ()
>      S.init(first);
>      int second = 2;
>      auto s = S(second);
>      assert(s.first == first);
>      assert(s.second == second);
> }
> 
> struct S
> {
>      static int first;
>      int second;
> 
>      // I'm aware of the fact, that nobody should redefine init() like:
>      // static auto init() { writeln("oh-oh..."); }
> 
>      static void init(int fParam) { first = fParam; }

This should also be disallowed. In order to know x.init means what it 
normally means, we shouldn't allow overriding it. This is the point of 
this thread, and the impetus for renaming of TypeInfo.init().

> 
>      this(int sParam) { second = sParam; }
> }
> /// --- code --- ///
> 
> My question has some components:
> 
> 1. If this also should be disallowed: why, as it could be possible, that 
> I'm not aware of existence of any init property of every struct.

The .init property is provided by the compiler, unless you define it. It 
means the default value of the type.

> 2. Regardless of the result of the first question, line 4 of the example 
> yields an error, although I didn't touch the standard init property. Why?

Once you override the property, the compiler will always use that. You 
can't override a name and then have it fall back on the default name for 
a different overload. D is very careful to resolve symbol names in an 
unambiguous way.

> 3. A practical aspect: What I try to solve is a two-stage initialization 
> of an object. I know, this should be avoided. In order to do this, I try 
> to separate the initializations of the type and its objects.
> (By the way, is this the right way to go?)

What you can do is simply rename the static method. Certainly a valid 
route to have a method to initialize the type variables.

Note that the way you have it, 'first' is a thread-local variable, so it 
would have to be initialized in every thread.

> Of course, I could use an external function, say
> prepareType(S)(int fParam)
> to do so, and this is the place, where I remembered the old posting and 
> found the current one.

Whether you put it inside the type or not is a preference. Either way is 
fine. It just shouldn't be named init if it's a member.

> As we are already beyond 2.075, are there known tickets about the 
> disabling of the ability to override the init property, where I can post 
> the bug of the second question, in case it is one?

Clearly, we have dropped the ball on deprecating this. Not sure if there 
is a ticket on it. I'll make one for the time being. We should try 
deprecating it by 2.078 (overriding init that is).

-Steve


More information about the Digitalmars-d-learn mailing list