digitalmars.D - Bug in using string mixins inside of a struct?
- Joseph Cassman (29/29) Mar 26 2013 I get these errors
- John Colvin (2/31) Mar 26 2013 It's bad code. What were you hoping for the code to do?
- John Colvin (3/43) Mar 26 2013 Sorry, I didn't read the code properly.
- Joseph Cassman (8/14) Mar 26 2013 Yeah, sadly artificial examples also remove the motive behind the
- Timon Gehr (12/39) Mar 26 2013 Bad code. Use enum for compile-time constants.
- John Colvin (6/56) Mar 26 2013 Perhaps you can enlighten me:
- Joseph Cassman (4/64) Mar 26 2013 Interesting. Didn't catch the difference a minute ago.
- Timon Gehr (36/58) Mar 27 2013 const c has memory allocated at run time, it would need to be a field of...
- kenji hara (11/19) Mar 27 2013 In above case, 's' cannot make a field in S.
- Timon Gehr (6/20) Mar 27 2013 Non-static variables should just be disallowed, as they are in the
- Joseph Cassman (7/20) Mar 26 2013 I agree. No need for the memory allocation in this case.
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
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 JosephIt's bad code. What were you hoping for the code to do?
Mar 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:Sorry, I didn't read the code properly. The template should be outside of the struct, then it works.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 JosephIt's bad code. What were you hoping for the code to do?
Mar 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: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[...] 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
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
On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:On 03/26/2013 10:28 PM, Joseph Cassman wrote: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?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
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:Interesting. Didn't catch the difference a minute ago. I am interested too in how and why they get treated differently. JosephOn 03/26/2013 10:28 PM, Joseph Cassman wrote: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?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
On 03/27/2013 12:22 AM, John Colvin wrote:On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote: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.... 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?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
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
Mar 27 2013
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
On Tuesday, 26 March 2013 at 23:00:40 UTC, Timon Gehr wrote:On 03/26/2013 10:28 PM, Joseph Cassman wrote: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[...]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