Struct ctor called with cast

Radu void at null.pt
Tue Feb 27 20:59:30 UTC 2018


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.


More information about the Digitalmars-d-learn mailing list