www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Casting Structs

reply "Paul D Anderson" <claude.rains msn.com> writes:
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
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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; }
May 31 2014
next sibling parent "Paul D Anderson" <claude.rains msn.com> writes:
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.
May 31 2014
prev sibling parent reply Philippe Sigaud via Digitalmars-d-learn writes:
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?
Jun 01 2014
parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jun 01 2014