Re: Struct ctor called with cast

2018-02-27 Thread Radu via Digitalmars-d-learn

On Tuesday, 27 February 2018 at 21:04:59 UTC, ag0aep6g wrote:

On 02/27/2018 09:59 PM, Radu wrote:

On Tuesday, 27 February 2018 at 20:51:25 UTC, ag0aep6g wrote:

On 02/27/2018 09:30 PM, Radu wrote:

[...]

[...]

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


In your original code (quoted above), you've got a templated 
constructor. The `Type` in `this(Type)(Type t)` is not the 
enum. It's a template parameter of the constructor.


To get a non-templated constructor that takes a `Type` (the 
enum), you have to write:



this(Type t) /* NOTE: Only one set of parentheses. */
{
/* ... */
}



Understood, make sense now, thanks!


Re: Struct ctor called with cast

2018-02-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/27/18 3:59 PM, Radu wrote:

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);
}


[snip]

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


Look at your constructor. You actually have a TEMPLATED constructor 
inside a TEMPLATED type.


In other words, inside your constructor, `Type` is not an enum Type, 
it's actually a void *.


It becomes clearer if you change the name of the second template parameter:

struct S(Type t = Type.a)
{
   this(T)(T t)
   {
   import std.stdio;
   writeln("ctor called.");
   }
}

-Steve


Re: Struct ctor called with cast

2018-02-27 Thread ag0aep6g via Digitalmars-d-learn

On 02/27/2018 09:59 PM, Radu wrote:

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.");
 }
}

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


In your original code (quoted above), you've got a templated 
constructor. The `Type` in `this(Type)(Type t)` is not the enum. It's a 
template parameter of the constructor.


To get a non-templated constructor that takes a `Type` (the enum), you 
have to write:



this(Type t) /* NOTE: Only one set of parentheses. */
{
/* ... */
}



Re: Struct ctor called with cast

2018-02-27 Thread Radu via Digitalmars-d-learn

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.


Re: Struct ctor called with cast

2018-02-27 Thread ag0aep6g via Digitalmars-d-learn

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


Struct ctor called with cast

2018-02-27 Thread Radu via Digitalmars-d-learn

I have this:




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.