www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why is my structure template does not compile?

reply Weed <resume755 mail.ru> writes:
struct S( Element )
{
     Element[] data;

     this( in uint len )
     {
         data.length = len;
     }

     ref Element opIndex( in uint n )
     {
         return data[n];
     }

     ref Element opIndexAssign( in Element a, in uint n )
     {
         data[n] += a;
         return data[n];
     }

     invariant()
     {
	// If I comment out next line compilation goes smoothly:
         assert( Element.sizeof > 0 );
     }
}

void main()
{
     alias S!(double) st;
     st test = st(20);
     auto a = test[2];
     test[2] = 3;
}

compilation error:
$ dmd demostruct
Error: __result = this is not an lvalue
demostruct.d(12): Error: __result = (this.data[n]) is not an lvalue
demostruct.d(18): Error: __result = (this.data[n]) is not an lvalue
demostruct.d(29): template instance demostruct.S!(double) error 
instantiating
Dec 11 2008
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Weed,


 ref Element opIndex( in uint n )
 {
 return data[n];
 }

 ref Element opIndexAssign( in Element a, in uint n )
 {
 data[n] += a;
 return data[n];
 }

I'm guessing as I don't use 2.0 but I think that this is a bug. DMD is trying to say that the above returns are trying to return something that can't be referenced (like a math expression result).
 invariant()
 {
 // If I comment out next line compilation goes smoothly:
 assert( Element.sizeof > 0 );
 }

OTOH that assert is wrong. Element.sizeof will always return 8, the size of an array reference. What you want is Element.length.
Dec 11 2008
parent Weed <resume755 mail.ru> writes:
 ref Element opIndexAssign( in Element a, in uint n )
 {
 data[n] += a;
 return data[n];
 }

I'm guessing as I don't use 2.0 but I think that this is a bug. DMD is trying to say that the above returns are trying to return something that can't be referenced (like a math expression result).

It is a bug, indeed. The struct 'invariant' prevents proper template instantiation somehow... Removing it makes code work as intended. I'll submit a bug report.

Thank you! Give a link to the bugreport later?
Dec 11 2008
prev sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 12 Dec 2008 02:21:11 +0300, BCS <ao pathlink.com> wrote:

 Reply to Weed,


 ref Element opIndex( in uint n )
 {
 return data[n];
 }

 ref Element opIndexAssign( in Element a, in uint n )
 {
 data[n] += a;
 return data[n];
 }

I'm guessing as I don't use 2.0 but I think that this is a bug. DMD is trying to say that the above returns are trying to return something that can't be referenced (like a math expression result).

It is a bug, indeed. The struct 'invariant' prevents proper template instantiation somehow... Removing it makes code work as intended. I'll submit a bug report.
 invariant()
 {
 // If I comment out next line compilation goes smoothly:
 assert( Element.sizeof > 0 );
 }

OTOH that assert is wrong. Element.sizeof will always return 8, the size of an array reference. What you want is Element.length.

No, I don't think so. Don't confuse 'Element' with 'data'. Element is a type, it doesn't have a length property. But it does have sizeof (an example of Element is an 'int', which is 4 bytes long).
Dec 11 2008
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Denis,

 On Fri, 12 Dec 2008 02:21:11 +0300, BCS <ao pathlink.com> wrote:
 
 Reply to Weed,

 invariant()
 {
 // If I comment out next line compilation goes smoothly:
 assert( Element.sizeof > 0 );
 }

size of an array reference. What you want is Element.length.

a type, it doesn't have a length property. But it does have sizeof (an example of Element is an 'int', which is 4 bytes long).

Oh, fud. I did get that wrong. I still think it's wrong as I'm not sure anything has 0 sizeof and even then that should be static assert.
Dec 11 2008
parent Weed <resume755 mail.ru> writes:
BCS пишет:
 Reply to Denis,
 
 On Fri, 12 Dec 2008 02:21:11 +0300, BCS <ao pathlink.com> wrote:

 Reply to Weed,

 invariant()
 {
 // If I comment out next line compilation goes smoothly:
 assert( Element.sizeof > 0 );
 }

size of an array reference. What you want is Element.length.

a type, it doesn't have a length property. But it does have sizeof (an example of Element is an 'int', which is 4 bytes long).

Oh, fud. I did get that wrong. I still think it's wrong as I'm not sure anything has 0 sizeof and even then that should be static assert.

You are right. It happens that the verification Element not null. static assert would be better.
Dec 11 2008
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 12 Dec 2008 02:47:42 +0300, BCS <ao pathlink.com> wrote:

 Reply to Denis,

 On Fri, 12 Dec 2008 02:21:11 +0300, BCS <ao pathlink.com> wrote:

 Reply to Weed,

 invariant()
 {
 // If I comment out next line compilation goes smoothly:
 assert( Element.sizeof > 0 );
 }

size of an array reference. What you want is Element.length.

a type, it doesn't have a length property. But it does have sizeof (an example of Element is an 'int', which is 4 bytes long).

Oh, fud. I did get that wrong. I still think it's wrong as I'm not sure anything has 0 sizeof and even then that should be static assert.

No, zero-sized arrays are allowed in D: struct Palette { uint size; ARGB[0] colors } Palette* createPalette(int numColors) { return cast(Palette*)GC.malloc(uint.sizeof + numColors * ARGB.sizeof); }
Dec 11 2008