Jump to page: 1 2
Thread overview
Bug in using string mixins inside of a struct?
Mar 26, 2013
Joseph Cassman
Mar 26, 2013
John Colvin
Mar 26, 2013
John Colvin
Mar 26, 2013
Joseph Cassman
Mar 26, 2013
Timon Gehr
Mar 26, 2013
John Colvin
Mar 26, 2013
Joseph Cassman
Mar 27, 2013
Timon Gehr
Mar 27, 2013
kenji hara
Mar 27, 2013
Timon Gehr
Mar 26, 2013
Joseph Cassman
March 26, 2013
I get these errors

aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use template to add field to aggregate 'A'
aggregate.d(6): Error: template instance aggregate.A.c!("y") error instantiating

from compiling the following code

struct A
{
    void b()
    {
        size_t y;
        mixin(c!("y"));
    }

    template c(string x)
    {
        const char[] c = "
            while(" ~ x ~ " < 100)
            {
                " ~ x ~ "++;
            }";
    }
}

I can only find bug 276 (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related but looks like it was fixed.

I am using dmd 2.062 on Ubuntu Linux 12.10.

Is this a bug? Or maybe bad code?

Thanks

Joseph
March 26, 2013
On Tuesday, 26 March 2013 at 21:28:16 UTC, Joseph Cassman wrote:
> I get these errors
>
> aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use template to add field to aggregate 'A'
> aggregate.d(6): Error: template instance aggregate.A.c!("y") error instantiating
>
> from compiling the following code
>
> struct A
> {
>     void b()
>     {
>         size_t y;
>         mixin(c!("y"));
>     }
>
>     template c(string x)
>     {
>         const char[] c = "
>             while(" ~ x ~ " < 100)
>             {
>                 " ~ x ~ "++;
>             }";
>     }
> }
>
> I can only find bug 276 (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related but looks like it was fixed.
>
> I am using dmd 2.062 on Ubuntu Linux 12.10.
>
> Is this a bug? Or maybe bad code?
>
> Thanks
>
> Joseph

It's bad code. What were you hoping for the code to do?
March 26, 2013
On Tuesday, 26 March 2013 at 22:35:46 UTC, John Colvin wrote:
> On Tuesday, 26 March 2013 at 21:28:16 UTC, Joseph Cassman wrote:
>> I get these errors
>>
>> aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use template to add field to aggregate 'A'
>> aggregate.d(6): Error: template instance aggregate.A.c!("y") error instantiating
>>
>> from compiling the following code
>>
>> struct A
>> {
>>    void b()
>>    {
>>        size_t y;
>>        mixin(c!("y"));
>>    }
>>
>>    template c(string x)
>>    {
>>        const char[] c = "
>>            while(" ~ x ~ " < 100)
>>            {
>>                " ~ x ~ "++;
>>            }";
>>    }
>> }
>>
>> I can only find bug 276 (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related but looks like it was fixed.
>>
>> I am using dmd 2.062 on Ubuntu Linux 12.10.
>>
>> Is this a bug? Or maybe bad code?
>>
>> Thanks
>>
>> Joseph
>
> It's bad code. What were you hoping for the code to do?

Sorry, I didn't read the code properly.

The template should be outside of the struct, then it works.
March 26, 2013
On 03/26/2013 10:28 PM, Joseph Cassman wrote:
> I get these errors
>
> aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use
> template to add field to aggregate 'A'
> aggregate.d(6): Error: template instance aggregate.A.c!("y") error
> instantiating
>
> from compiling the following code
>
> struct A
> {
>      void b()
>      {
>          size_t y;
>          mixin(c!("y"));
>      }
>
>      template c(string x)
>      {
>          const char[] c = "
>              while(" ~ x ~ " < 100)
>              {
>                  " ~ x ~ "++;
>              }";
>      }
> }
>
> I can only find bug 276
> (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related
> but looks like it was fixed.
>
> I am using dmd 2.062 on Ubuntu Linux 12.10.
>
> Is this a bug? Or maybe bad code?
>

Bad code. Use enum for compile-time constants.

This will work:

struct A{
    void b(){
        size_t y;
        mixin(c!("y"));
    }

    template c(string x){
        enum c = "while(" ~ x ~ " < 100){" ~ x ~ "++;}";
    }
}

March 26, 2013
On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:
> On 03/26/2013 10:28 PM, Joseph Cassman wrote:
>> I get these errors
>>
>> aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use
>> template to add field to aggregate 'A'
>> aggregate.d(6): Error: template instance aggregate.A.c!("y") error
>> instantiating
>>
>> from compiling the following code
>>
>> struct A
>> {
>>     void b()
>>     {
>>         size_t y;
>>         mixin(c!("y"));
>>     }
>>
>>     template c(string x)
>>     {
>>         const char[] c = "
>>             while(" ~ x ~ " < 100)
>>             {
>>                 " ~ x ~ "++;
>>             }";
>>     }
>> }
>>
>> I can only find bug 276
>> (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related
>> but looks like it was fixed.
>>
>> I am using dmd 2.062 on Ubuntu Linux 12.10.
>>
>> Is this a bug? Or maybe bad code?
>>
>
> Bad code. Use enum for compile-time constants.
>
> This will work:
>
> struct A{
>     void b(){
>         size_t y;
>         mixin(c!("y"));
>     }
>
>     template c(string x){
>         enum c = "while(" ~ x ~ " < 100){" ~ x ~ "++;}";
>     }
> }

Perhaps you can enlighten me:

why does "const c" work if the template is outside the struct, but not if it's inside?

Also, why doesn't "string c" work even outside of the struct, seeing as it's value is completely defined at compile-time?
March 26, 2013
On Tuesday, 26 March 2013 at 22:43:28 UTC, John Colvin wrote:
> On Tuesday, 26 March 2013 at 22:35:46 UTC, John Colvin wrote:
>> [...]
>>
>> It's bad code. What were you hoping for the code to do?
>
> Sorry, I didn't read the code properly.
>
> The template should be outside of the struct, then it works.

Yeah, sadly artificial examples also remove the motive behind the code. Thanks for taking a look anyways. Mainly the idea is to remove redundancy, but inside of a struct.

Moving the template outside the struct in my original code fixes the problem.
Thanks!

Joseph
March 26, 2013
On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:
> On 03/26/2013 10:28 PM, Joseph Cassman wrote:
>> [...]
>
> Bad code. Use enum for compile-time constants.
>
> This will work:
>
> struct A{
>     void b(){
>         size_t y;
>         mixin(c!("y"));
>     }
>
>     template c(string x){
>         enum c = "while(" ~ x ~ " < 100){" ~ x ~ "++;}";
>     }
> }

I agree. No need for the memory allocation in this case.
Perhaps the example on the tutorial page could be updated accordingly.

http://dlang.org/mixin.html

Appreciate the help

Joseph
March 26, 2013
On Tuesday, 26 March 2013 at 23:22:03 UTC, John Colvin wrote:
> On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:
>> On 03/26/2013 10:28 PM, Joseph Cassman wrote:
>>> I get these errors
>>>
>>> aggregate.d(11): Error: variable aggregate.A.c!("y").c cannot use
>>> template to add field to aggregate 'A'
>>> aggregate.d(6): Error: template instance aggregate.A.c!("y") error
>>> instantiating
>>>
>>> from compiling the following code
>>>
>>> struct A
>>> {
>>>    void b()
>>>    {
>>>        size_t y;
>>>        mixin(c!("y"));
>>>    }
>>>
>>>    template c(string x)
>>>    {
>>>        const char[] c = "
>>>            while(" ~ x ~ " < 100)
>>>            {
>>>                " ~ x ~ "++;
>>>            }";
>>>    }
>>> }
>>>
>>> I can only find bug 276
>>> (http://d.puremagic.com/issues/show_bug.cgi?id=276) which seems related
>>> but looks like it was fixed.
>>>
>>> I am using dmd 2.062 on Ubuntu Linux 12.10.
>>>
>>> Is this a bug? Or maybe bad code?
>>>
>>
>> Bad code. Use enum for compile-time constants.
>>
>> This will work:
>>
>> struct A{
>>    void b(){
>>        size_t y;
>>        mixin(c!("y"));
>>    }
>>
>>    template c(string x){
>>        enum c = "while(" ~ x ~ " < 100){" ~ x ~ "++;}";
>>    }
>> }
>
> Perhaps you can enlighten me:
>
> why does "const c" work if the template is outside the struct, but not if it's inside?
>
> Also, why doesn't "string c" work even outside of the struct, seeing as it's value is completely defined at compile-time?

Interesting. Didn't catch the difference a minute ago.
I am interested too in how and why they get treated differently.

Joseph
March 27, 2013
On 03/27/2013 12:22 AM, John Colvin wrote:
> On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:
>> ...
>>
>> Bad code. Use enum for compile-time constants.
>>
>> This will work:
>>
>> struct A{
>>     void b(){
>>         size_t y;
>>         mixin(c!("y"));
>>     }
>>
>>     template c(string x){
>>         enum c = "while(" ~ x ~ " < 100){" ~ x ~ "++;}";
>>     }
>> }
>
> Perhaps you can enlighten me:
>
> why does "const c" work if the template is outside the struct, but not
> if it's inside?
>

const c has memory allocated at run time, it would need to be a field of A. Because the number of template instantiations is not bounded a priori, templates cannot be used to add fields to aggregates:

struct S{
    template T(int x){
        const s = x; // would need one field per instantiation
    }
}

void main(){
    S s;
    auto a = S.T!0.s;
}

struct S{
    template T(int x){
        static const s = x; // static variables work
    }
}

...

Because of a questionable patch (written by Kenji Hara, I think) some time ago, the following works:

struct S{
    template T(int x){
        auto s = x; // implicitly static
    }
}

...

I consider this bad language design.

> Also, why doesn't "string c" work even outside of the struct, seeing as
> it's value is completely defined at compile-time?

It is a design decision. Only variables initialized at compile time that may not be mutated at run time can be read at compile time.

string c = "123";
immutable d = "1234";

void main(){
    c = "456"; // may change, cannot be read at compile time
    enum x = d; // may not change, can be read at compile time
}




March 27, 2013
2013/3/27 Timon Gehr <timon.gehr@gmx.ch>

> Because of a questionable patch (written by Kenji Hara, I think) some time
> ago, the following works:
>
> struct S{
>     template T(int x){
>         auto s = x; // implicitly static
>     }
> }
>
> I consider this bad language design.


In above case, 's' cannot make a field in S.
Because such a feature would make impossible to determine the size of S.

void main() {
    S s;
    assert(s.T!0.s == 0);  // If T!0.s is a field of s,
    assert(s.T!1.s == 1);  // also T!1.s is a field...
    pragma(msg, S.sizeof == ??);  // ???
}

So, variables in template declaration will always make "static' variables.

Kenji Hara


« First   ‹ Prev
1 2