Bug 12120 – Static opCall for structures skipped (Github HEAD)

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-02-09T10:32:00Z
Last change time
2014-02-09T19:35:13Z
Assigned to
nobody
Creator
puneet

Comments

Comment #0 by puneet — 2014-02-09T10:32:02Z
Here is the reduced code. struct Foo { this(int) {} static Foo opCall() { import std.stdio; writeln("opCall"); Foo foo = Foo(0); return foo; } } void main() { Foo foo = Foo(); }
Comment #1 by puneet — 2014-02-09T10:34:16Z
Seems to be due to fix12070.
Comment #2 by k.hara.pg — 2014-02-09T17:30:31Z
(In reply to comment #0) > Here is the reduced code. > > struct Foo { > this(int) {} > static Foo opCall() { > import std.stdio; > writeln("opCall"); > Foo foo = Foo(0); > return foo; > } > } > > void main() { > Foo foo = Foo(); > } If you define constructors in a struct, the syntax `Type()` should be reserved for default construction. If you want to support both Foo() and Foo(1), you should change the constructor to static Foo opCall(int).
Comment #3 by puneet — 2014-02-09T18:04:52Z
> > If you define constructors in a struct, the syntax `Type()` should be reserved > for default construction. > > If you want to support both Foo() and Foo(1), you should change the constructor > to static Foo opCall(int). I am sorry if I missed something, but how do I initialize a struct object element from a call to Foo()? I believe default constructors are not allowed for structs. Say: class Bar {} struct Foo { Bar bar; // bar is not static static Foo opCall() { // I want to return a Foo object with bar initialized // How can I achieve that?? } this() { // Does not compile bar = new Bar(); } }
Comment #4 by dlang-bugzilla — 2014-02-09T18:12:04Z
(In reply to comment #2) > If you define constructors in a struct, the syntax `Type()` should be reserved > for default construction. > > If you want to support both Foo() and Foo(1), you should change the constructor > to static Foo opCall(int). If I understood this change correctly, I don't think it is a good change, as I mentioned in the pull request: https://github.com/D-Programming-Language/dmd/pull/3221 This issue only serves as further evidence towards that. (In reply to comment #3) > I am sorry if I missed something, but how do I initialize a struct object > element from a call to Foo()? I believe default constructors are not allowed > for structs. static Foo opCall() { Foo foo; foo.bar = ...; return foo; }
Comment #5 by puneet — 2014-02-09T18:25:16Z
> static Foo opCall() > { > Foo foo; > foo.bar = ...; > return foo; > } Thanks Vladimir. Kenji the idea that this syntax "Foo foo = Foo();" would not be supported if another constructor is available is a bit too constraining.
Comment #6 by k.hara.pg — 2014-02-09T19:35:13Z
(In reply to comment #4) > If I understood this change correctly, I don't think it is a good change, as I > mentioned in the pull request: > https://github.com/D-Programming-Language/dmd/pull/3221 > > This issue only serves as further evidence towards that. I opened an enhancement issue 12124. (In reply to comment #5) > Kenji the idea that this syntax "Foo foo = Foo();" would not be supported if > another constructor is available is a bit too constraining. Do complex work with the syntax Foo() is not recommended in D language design. In D, Foo foo = Foo(); is normally equivalent with Foo foo;. It is important in generic code.