Comment #0 by bearophile_hugs — 2012-02-26T16:19:31Z
This program comes from a reduction of a bug I've found:
struct Foo {
void init() {}
}
void main() {
Foo*[] foos;
(*foos[0]).init(); // OK
foos[0].init(); // Error: function expected before (), not null of type Foo*
}
I suggest to statically disallow the definition of a init() method in structs (especially if they are a @property).
Some persons seem to agree.
See also the discussion:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=32944
------------------
Timon Gehr shows a case where defining a struct "init" method is useful, this code compiles unless you de-comment the struct init. But maybe this is just a bug in the implementation of @disable:
struct Foo {
@disable this();
// @disable enum init = 0;
}
void main() {
Foo f = Foo.init;
}
Comment #1 by monarchdodra — 2014-04-08T08:19:34Z
(In reply to comment #0)
> Timon Gehr shows a case where defining a struct "init" method is useful, this
> code compiles unless you de-comment the struct init. But maybe this is just a
> bug in the implementation of @disable:
>
>
> struct Foo {
> @disable this();
> // @disable enum init = 0;
> }
> void main() {
> Foo f = Foo.init;
> }
Arguably, the "Foo f = Foo.init;" *should* be guaranteed to *always* work. Finding a way to break it would be *catastrophic* for generic phobos code.
The formulation is meant as a verbose way of saying
- YES! I know that Foo is const/hasDisableThis, and I know I should be initializing it to an explicit value. But for gods sake, this is generic code and I need an instance regardless! Just use "T.init". I'll assume the consequences.
More often than not, it is need for traits, where "f" would never be used anyways.
It is also safer alternative to void initialization (that don't work with const anyways): should a throwing function be located between the declaration, and the subsequent emplace construction, at least, the destructor will be called on non-garbage, and the specs *do* say that T.init should always be destroyable.
See also:
https://d.puremagic.com/issues/show_bug.cgi?id=8752
Where Kenji suggests that some uses of "Foo f = Foo.init;" be made unsafe under certain situations.
Comment #2 by davidsp — 2014-07-25T00:53:26Z
We either should forbid a method named init (or any other valid type properties) or require and explizit "override".
This isn't related to only structs, e.g.:
class A
{
void init() {}
}
void t(T)()
{
auto x = T.init;
}
int main(string[] args)
{
t!A();
}
-> test.d(10): Error: need 'this' for 'init' of type 'void()'.
The bug is more: "Don't allow shadowing of type properties".
Comment #3 by default_357-line — 2020-04-21T06:45:57Z
*reaches up*
> It has been [0] days since a user was hit by this bug.
There's simply no value to this. If you want a constructor, write a constructor. Overriding "T.init" is always an error, and should be reported as one by the compiler.
Comment #4 by robert.schadek — 2024-12-13T17:58:42Z