www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug in using string mixins inside of a struct?

reply "Joseph Cassman" <jc7919 outlook.com> writes:
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
Mar 26 2013
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
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?
Mar 26 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
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.
Mar 26 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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 ~ "++;}"; } }
Mar 26 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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 }
Mar 27 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/27/2013 12:33 PM, kenji hara wrote:
 2013/3/27 Timon Gehr <timon.gehr gmx.ch <mailto: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.

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

 ...

Non-static variables should just be disallowed, as they are in the 'const' case. Implicitly adding static does not reduce confusion. Furthermore, it would be ok to template function-local variables, a nice future extension that is blocked by this design.
Mar 27 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
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?
Mar 26 2013
prev sibling next sibling parent "Joseph Cassman" <jc7919 outlook.com> writes:
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
Mar 26 2013
prev sibling next sibling parent "Joseph Cassman" <jc7919 outlook.com> writes:
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
Mar 26 2013
prev sibling next sibling parent "Joseph Cassman" <jc7919 outlook.com> writes:
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
Mar 26 2013
prev sibling parent kenji hara <k.hara.pg gmail.com> writes:
--f46d0435c010800abc04d8e666d5
Content-Type: text/plain; charset=UTF-8

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 --f46d0435c010800abc04d8e666d5 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">2013/3/27 Timon Gehr <span dir=3D"ltr">&lt;<a href=3D"mail= to:timon.gehr gmx.ch" target=3D"_blank">timon.gehr gmx.ch</a>&gt;</span><br=
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D=

r-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <div class=3D"im"><span style=3D"color:rgb(34,34,34)">Because of a question= able patch (written by Kenji Hara, I think) some time ago, the following wo= rks:</span><br></div> <br> struct S{<br> =C2=A0 =C2=A0 template T(int x){<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto s =3D x; // implicitly static<br> =C2=A0 =C2=A0 }<br> }<br> <br>I consider this bad language design.</blockquote><div><br></div><div st= yle>In above case, &#39;s&#39; cannot make a field in S.</div><div style>Be= cause such a feature would make impossible to determine the size of S.</div=

S s;</div><div style>=C2=A0 =C2=A0 assert(s.T!0.s =3D=3D 0); =C2=A0// If T= !0.s is a field of s,</div><div style>=C2=A0 =C2=A0 assert(s.T!1.s =3D=3D 1= ); =C2=A0// also T!1.s is a field...</div><div style> =C2=A0 =C2=A0 pragma(msg, S.sizeof =3D=3D ??); =C2=A0// ???</div><div style=
}</div><div style><br></div><div style>So, variables in template declarati=

div><div style> Kenji Hara</div></div></div></div> --f46d0435c010800abc04d8e666d5--
Mar 27 2013