Thread overview
Casting Structs
May 31, 2014
Paul D Anderson
May 31, 2014
Ali Çehreli
May 31, 2014
Timon Gehr
Jun 01, 2014
Paul D Anderson
Jun 01, 2014
Philippe Sigaud
Jun 01, 2014
Timon Gehr
May 31, 2014
I'm working on the decimal number package for D. A decimal is a struct with precision, max exponent and rounding mode parameters: "Decimal!(PRECISION, MAX_EXPO, ROUNDING)". I was trying to overload the opCast operator for this struct and I found that it does not seem necessary. I can cast decimals with different precisions, etc., back and forth without overloading opCast.

This code works:

alias dec9  = Decimal!(9,99);
alias dec10 = Decimal!(10,99);

dec9 bingo = dec9("123.45");
dec10 little = cast(dec10(bingo));

assert(little == dec10("123.45"));

Is this expected behavior?

Paul

May 31, 2014
On 05/31/2014 02:11 PM, Paul D Anderson wrote:
> I'm working on the decimal number package for D. A decimal is a struct
> with precision, max exponent and rounding mode parameters:
> "Decimal!(PRECISION, MAX_EXPO, ROUNDING)". I was trying to overload the
> opCast operator for this struct and I found that it does not seem
> necessary. I can cast decimals with different precisions, etc., back and
> forth without overloading opCast.
>
> This code works:
>
> alias dec9  = Decimal!(9,99);
> alias dec10 = Decimal!(10,99);
>
> dec9 bingo = dec9("123.45");
> dec10 little = cast(dec10(bingo));

You meant cast(dec10)(bingo).

> assert(little == dec10("123.45"));
>
> Is this expected behavior?
>
> Paul
>

That is surprising. I've discovered that if the template has members that depend on a template parameter than the code fails to compile. I think it should fail to compile in other cases as well because a separate instantiation of a template is a separate type potentially with completely different invariants.

Here is reduced code that fails to compile:

struct Decimal(int A, int B)
{
    int[A] arrA;// Replace this with something that does not depend on a
                // template parameter and the code compiles.

    this(string)
    {}
}

alias dec9  = Decimal!(9,99);
alias dec10 = Decimal!(10,99);

void main()
{
    dec9 bingo = dec9("123.45");
    dec10 little = cast(dec10)(bingo);

    assert(little == dec10("123.45"));
}

Ali

May 31, 2014
On 06/01/2014 12:25 AM, Ali Çehreli wrote:
>>
>> dec10 little = cast(dec10(bingo));
>
> You meant cast(dec10)(bingo).
>
>> assert(little == dec10("123.45"));
>>
>> Is this expected behavior?
>>
>> Paul
>>
>
> That is surprising. I've discovered that if the template has members
> that depend on a template parameter than the code fails to compile. I
> think it should fail to compile in other cases as well because a
> separate instantiation of a template is a separate type potentially with
> completely different invariants.

This behaviour is independent of templates. Struct values of the same size can be reinterpret-cast to each other this way even if their types are completely unrelated.


struct A{
    int a,b;
}
struct B{
    long x;
}

void main(){
    auto a=A();
    auto b=cast(B)a;
}

June 01, 2014
On Saturday, 31 May 2014 at 22:34:45 UTC, Timon Gehr wrote:
> On 06/01/2014 12:25 AM, Ali Çehreli wrote:
>>>
>>> dec10 little = cast(dec10(bingo));
>>
>> You meant cast(dec10)(bingo).
>>
>>> assert(little == dec10("123.45"));
>>>
>>> Is this expected behavior?
>>>
>>> Paul
>>>
>>
>> That is surprising. I've discovered that if the template has members
>> that depend on a template parameter than the code fails to compile. I
>> think it should fail to compile in other cases as well because a
>> separate instantiation of a template is a separate type potentially with
>> completely different invariants.
>
> This behaviour is independent of templates. Struct values of the same size can be reinterpret-cast to each other this way even if their types are completely unrelated.
>
>
> struct A{
>     int a,b;
> }
> struct B{
>     long x;
> }
>
> void main(){
>     auto a=A();
>     auto b=cast(B)a;
> }

So, although this works it is undocumented and will probably be modified at some point. I won't use it and I'll file a bug report if I can't find one that covers it already. Thanks for your help.
June 01, 2014
On Sun, Jun 1, 2014 at 12:34 AM, Timon Gehr via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> This behaviour is independent of templates. Struct values of the same size can be reinterpret-cast to each other this way even if their types are completely unrelated.

Do you know if this is by design?
June 01, 2014
On 06/01/2014 09:59 AM, Philippe Sigaud via Digitalmars-d-learn wrote:
> On Sun, Jun 1, 2014 at 12:34 AM, Timon Gehr via Digitalmars-d-learn
> <digitalmars-d-learn@puremagic.com> wrote:
>
>> This behaviour is independent of templates. Struct values of the same size
>> can be reinterpret-cast to each other this way even if their types are
>> completely unrelated.
>
> Do you know if this is by design?
>

Well, it had to be explicitly implemented. The behaviour contradicts the documentation at http://dlang.org/expression#CastExpression though.