On Tuesday, 27 February 2018 at 20:51:25 UTC, ag0aep6g wrote:
On 02/27/2018 09:30 PM, Radu wrote:

enum Type { a };
struct S(Type t = Type.a)
{
     this(Type)(Type t)
     {
         import std.stdio;
         writeln("ctor called.");
     }
}
void main()
{
    auto x = S!(Type.a)(Type.a);
    void* y = &x;
    auto z = (cast(S!(Type.a)) y);
}


Surprisingly the cast will actually call the ctor. Is this to be expected? Sure looks like a bug to me, as a non templated S will complain about the cast.

Not a bug. The spec says [1]: "Casting a value v to a struct S, when value is not a struct of the same type, is equivalent to: S(v)"

Templates have nothing to do with it. Your code boils down to this:

----
struct S
{
    this(void* t)
    {
        import std.stdio;
        writeln("ctor called.");
    }
}
void main()
{
   void* y;
   auto z = cast(S) y;
}
----


[1] https://dlang.org/spec/expression.html#cast_expressions

OK, got it - thanks.

But this:


struct S
{
    this(int t)
    {
        import std.stdio;
        writeln("ctor called.");
    }
}
void main()
{
   auto x = S(1);
   void* y = &x;
   auto z = (cast(S) y);
}


Produces:
Error: cannot cast expression y of type void* to S

Which is kinda correct as I don't have any ctor in S taking a void*.

Adding



    this(void* t)
    {
        import std.stdio;
        writeln("ctor called.");
    }


Will make the error go away.


So the bug is that somehow the templated version makes it so there is an implicit void* ctor.

Reply via email to