Thread overview
Why is my structure template does not compile?
Dec 11, 2008
Weed
Dec 11, 2008
BCS
Dec 11, 2008
Denis Koroskin
Dec 11, 2008
Weed
Dec 11, 2008
BCS
Dec 11, 2008
Weed
Dec 12, 2008
Denis Koroskin
December 11, 2008
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
December 11, 2008
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.


December 11, 2008
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).
December 11, 2008
>>> 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?
December 11, 2008
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 );
>>> }
>> 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).
> 

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.


December 11, 2008
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 );
>>>> }
>>> 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).
>>
> 
> 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.
December 12, 2008
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 );
>>>> }
>>> 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).
>>
>
> 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);
}