Thread overview
Struct constructors and opCall
Mar 17, 2009
Lars Kyllingstad
Mar 18, 2009
Robert Fraser
Mar 18, 2009
Gide Nwawudu
March 17, 2009
I've come across the following strange behaviour in D2. Consider a struct with a constructor, static opCall and non-static opCall:

    import std.stdio;

    struct Foo
    {
        this(int i)               { writefln("constructor"); }
        static void opCall(int i) { writefln("static opCall"); }
        void opCall(int i)        { writefln("instance opCall"); }
    }

    void main()
    {
        auto foo = Foo(1);
        Foo(1);
        foo(1);
    }

I expected that either compilation should fail because of ambiguity, or the program should compile and run with the following output:

    constructor
    static opCall
    instance opCall

Instead, compiled with the newest DMD (2.026), it prints

    constructor
    constructor
    constructor

This has to be a bug. Is it a known one? I tried searching for "struct constructor opCall" in both Bugzilla and Google, but couldn't find anything.

-Lars
March 18, 2009
Lars Kyllingstad wrote:
> I've come across the following strange behaviour in D2. Consider a struct with a constructor, static opCall and non-static opCall:
> 
>     import std.stdio;
> 
>     struct Foo
>     {
>         this(int i)               { writefln("constructor"); }
>         static void opCall(int i) { writefln("static opCall"); }
>         void opCall(int i)        { writefln("instance opCall"); }
>     }
> 
>     void main()
>     {
>         auto foo = Foo(1);
>         Foo(1);
>         foo(1);
>     }
> 
> I expected that either compilation should fail because of ambiguity, or the program should compile and run with the following output:
> 
>     constructor
>     static opCall
>     instance opCall
> 
> Instead, compiled with the newest DMD (2.026), it prints
> 
>     constructor
>     constructor
>     constructor
> 
> This has to be a bug. Is it a known one? I tried searching for "struct constructor opCall" in both Bugzilla and Google, but couldn't find anything.
> 
> -Lars

You can always report it as a bug and if its a duplicate; it'll be closed as one.
March 18, 2009
On Tue, 17 Mar 2009 11:59:42 +0100, Lars Kyllingstad <public@kyllingen.NOSPAMnet> wrote:

>I've come across the following strange behaviour in D2. Consider a struct with a constructor, static opCall and non-static opCall:
>
>     import std.stdio;
>
>     struct Foo
>     {
>         this(int i)               { writefln("constructor"); }
>         static void opCall(int i) { writefln("static opCall"); }
>         void opCall(int i)        { writefln("instance opCall"); }
>     }
>
>     void main()
>     {
>         auto foo = Foo(1);
>         Foo(1);
>         foo(1);
>     }
>
>I expected that either compilation should fail because of ambiguity, or the program should compile and run with the following output:
>
>     constructor
>     static opCall
>     instance opCall
>
>Instead, compiled with the newest DMD (2.026), it prints
>
>     constructor
>     constructor
>     constructor
>
>This has to be a bug. Is it a known one? I tried searching for "struct constructor opCall" in both Bugzilla and Google, but couldn't find anything.
>
>-Lars


http://www.digitalmars.com/d/archives/digitalmars/D/announce/DMD_1.035_and_2.019_releases_12806.html#N12833

Walter wrote:
"If there's any constructor defined for S, then S(args) is a
constructor call.

If there's any opCall defined for S, then S(args) is an opCall call.

Otherwise, it's a struct literal."


Gide
March 18, 2009
On Tue, Mar 17, 2009 at 10:23 PM, Gide Nwawudu <gide@btinternet.com> wrote:
> On Tue, 17 Mar 2009 11:59:42 +0100, Lars Kyllingstad <public@kyllingen.NOSPAMnet> wrote:
>
>>I've come across the following strange behaviour in D2. Consider a struct with a constructor, static opCall and non-static opCall:
>>
>>     import std.stdio;
>>
>>     struct Foo
>>     {
>>         this(int i)               { writefln("constructor"); }
>>         static void opCall(int i) { writefln("static opCall"); }
>>         void opCall(int i)        { writefln("instance opCall"); }
>>     }
>>
>>     void main()
>>     {
>>         auto foo = Foo(1);
>>         Foo(1);
>>         foo(1);
>>     }
>>
>>I expected that either compilation should fail because of ambiguity, or the program should compile and run with the following output:
>>
>>     constructor
>>     static opCall
>>     instance opCall
>>
>>Instead, compiled with the newest DMD (2.026), it prints
>>
>>     constructor
>>     constructor
>>     constructor
>>
>>This has to be a bug. Is it a known one? I tried searching for "struct constructor opCall" in both Bugzilla and Google, but couldn't find anything.
>>
>>-Lars
>
>
> http://www.digitalmars.com/d/archives/digitalmars/D/announce/DMD_1.035_and_2.019_releases_12806.html#N12833
>
> Walter wrote:
> "If there's any constructor defined for S, then S(args) is a
> constructor call.
>
> If there's any opCall defined for S, then S(args) is an opCall call.
>
> Otherwise, it's a struct literal."

foo(1) calling the constructor is almost certainly a bug, though.  It really should call the instance opCall.