www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug?: Presence of "init()" Method Causes std.array.appender to Fail to

reply Vijay Nayar <madric gmail.com> writes:
I encountered a very unexpected error when working on a project.  
It seems that the Appender and RefAppender structs created from 
the std.array.appender() method are sensitive to the mere 
presence of a method called "init()" on the element type of the 
array.

Here is a minimal example:

```
import std.array;

struct S1 {
   // The mere presence of this method causes the error, deleting 
it fixes the error.
   void init(string p1, int p2, int p3) { }
}

struct S2 {
   S1[] a;
   RefAppender!(int[]) getAppender() {
     return appender(&a);
   }
}

void main() { }
```

The compiler produces the following output:
```
/dlang/dmd/linux/bin64/../../src/phobos/std/array.d(2907): Error: 
cannot have array of `void(string, int, int)`
/dlang/dmd/linux/bin64/../../src/phobos/std/array.d(2976): Error: 
cannot have array of `inout void(string, int, int)`
/dlang/dmd/linux/bin64/../../src/phobos/std/array.d(3369): Error: 
template instance `std.array.Appender!(S1[])` error instantiating
/dlang/dmd/linux/bin64/../../src/phobos/std/array.d(3879):        
instantiated from here: `RefAppender!(S1[])`
onlineapp.d(12):        instantiated from here: `appender!(S1[]*, 
S1)`
/dlang/dmd/linux/bin64/../../src/phobos/std/array.d(3429): Error: 
cannot have array of `inout void(string, int, int)`
```

Is this a bug or a misunderstanding on my part?
May 13 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 13 May 2018 at 23:53:58 UTC, Vijay Nayar wrote:
 I encountered a very unexpected error when working on a 
 project.  It seems that the Appender and RefAppender structs 
 created from the std.array.appender() method are sensitive to 
 the mere presence of a method called "init()" on the element 
 type of the array.

 [...]
init is a reserved function. T.init is the initial value for a type. int.init is 0 and float.init is NaN. Try changing your function name to initialise or something like that.
May 13 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, May 14, 2018 00:04:20 Uknown via Digitalmars-d wrote:
 On Sunday, 13 May 2018 at 23:53:58 UTC, Vijay Nayar wrote:
 I encountered a very unexpected error when working on a
 project.  It seems that the Appender and RefAppender structs
 created from the std.array.appender() method are sensitive to
 the mere presence of a method called "init()" on the element
 type of the array.

 [...]
init is a reserved function. T.init is the initial value for a type. int.init is 0 and float.init is NaN. Try changing your function name to initialise or something like that.
Yeah. It's been discussed that it should be illegal to declare a struct or class member named init, but that change has yet to happen. https://issues.dlang.org/show_bug.cgi?id=7066 https://issues.dlang.org/show_bug.cgi?id=14237 That mistake was even made in some places in druntime and Phobos (e.g. TypeInfo in druntime and DirEntry in Phobos), and it caused problems. Those uses had to be fixed before we could look at actually making it illegal, and AFAIK, they've all been fixed, but the compiler has yet to be changed. I don't know if a DIP would be required or not though before it could happen. It was kind of informally agreed that it should be illegal to declare init, but I don't think that it was ever officially agreed upon. Regarldless, declaring init just causes bugs, and code shouldn't do it. - Jonathan M Davis
May 13 2018
parent reply Nick Treleaven <nick geany.org> writes:
On Monday, 14 May 2018 at 01:20:38 UTC, Jonathan M Davis wrote:
 Yeah. It's been discussed that it should be illegal to declare 
 a struct or class member named init, but that change has yet to 
 happen.

 https://issues.dlang.org/show_bug.cgi?id=7066
Walter and Timon have considered redefinition potentially useful. A compromise would be to require `init` and `stringof` to be `static`. That would probably prevent the accidental conflicts that arise with `init`.
May 14 2018
parent reply David Nadlinger <code klickverbot.at> writes:
On Monday, 14 May 2018 at 11:53:44 UTC, Nick Treleaven wrote:
 On Monday, 14 May 2018 at 01:20:38 UTC, Jonathan M Davis wrote:
 Yeah. It's been discussed that it should be illegal to declare 
 a struct or class member named init, but that change has yet 
 to happen.

 https://issues.dlang.org/show_bug.cgi?id=7066
Walter and Timon have considered redefinition potentially useful. A compromise would be to require `init` and `stringof` to be `static`. That would probably prevent the accidental conflicts that arise with `init`.
Well, Walter mentioned that "so far [no use cases] have materialized" in 2012, and I don't think that has changed since. disabling .init might be an exception – although one that flirts with grey areas in the language definition –, but that could still be supported while providing useful diagnostics for other uses. — David
May 14 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, May 14, 2018 18:29:33 David Nadlinger via Digitalmars-d wrote:
 On Monday, 14 May 2018 at 11:53:44 UTC, Nick Treleaven wrote:
 On Monday, 14 May 2018 at 01:20:38 UTC, Jonathan M Davis wrote:
 Yeah. It's been discussed that it should be illegal to declare
 a struct or class member named init, but that change has yet
 to happen.

 https://issues.dlang.org/show_bug.cgi?id=7066
Walter and Timon have considered redefinition potentially useful. A compromise would be to require `init` and `stringof` to be `static`. That would probably prevent the accidental conflicts that arise with `init`.
Well, Walter mentioned that "so far [no use cases] have materialized" in 2012, and I don't think that has changed since. disabling .init might be an exception – although one that flirts with grey areas in the language definition –, but that could still be supported while providing useful diagnostics for other uses.
Well, disable this(); specifically doesn't disable init (just default initialization) specifically because so much depends on init existing (and the fact that you can disable default initialization is already problematic enough as it is). So, I'd be _very_ leery of adding a way to fully disable init. However, even if we did want to do that, that doesn't preclude making it illegal to define init to be something else. - Jonathan M Davis
May 14 2018