Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statically disallow a init() method in structs #18418

Open
dlangBugzillaToGithub opened this issue Feb 26, 2012 · 4 comments
Open

Statically disallow a init() method in structs #18418

dlangBugzillaToGithub opened this issue Feb 26, 2012 · 4 comments

Comments

@dlangBugzillaToGithub
Copy link

bearophile_hugs reported this on 2012-02-26T16:19:31Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=7597

CC List

Description

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;
}
@dlangBugzillaToGithub
Copy link
Author

monarchdodra commented on 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.

@dlangBugzillaToGithub
Copy link
Author

davidsp commented on 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".

@dlangBugzillaToGithub
Copy link
Author

default_357-line (@FeepingCreature) commented on 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.

@ntrel
Copy link
Contributor

ntrel commented Dec 24, 2024

Timon Gehr shows a case where defining a struct "init" method is useful
...
Foo f = Foo.init;

Note that (Foo[1]).init[0] is not disabled, so it is not reliable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants