digitalmars.D - Struct initializers and const in 2.009
- torhu (21/21) Jan 06 2008 ---
- Sean Kelly (4/30) Jan 06 2008 Weird. With transitive const, I'd expect the assignment to be from
- torhu (32/32) Jan 06 2008 Another surprise I got was when doing something like this:
- Dan (13/13) Jan 06 2008 You actually managed to make your programs compatible with D 1.x and 2.x...
- torhu (10/25) Jan 07 2008 Maybe you could make it work with some casting, but it might not be
- Christopher Wright (5/39) Jan 07 2008 And then you can just do:
- Sean Kelly (10/44) Jan 07 2008 You don't need either one for the function parameter. Try this:
--- struct Foo { int val; } struct Bar { Foo f; //const Foo f; // workaround } const Foo foo = { 123 }; // line 11 const Bar bar = { f: foo // the problem is here }; --- bug.d(11): Error: cannot implicitly convert expression (Foo(123)) of type const(Foo) to Foo The problem here is that Bar.f is not const, while foo is. Since bar is const, shouldn't consts always be legal in the initializer? Or doesn't it work that way? The workaround for this is pretty simple, I know. foo could also be made an enum, but I need 1.x compatibility.
Jan 06 2008
torhu wrote:--- struct Foo { int val; } struct Bar { Foo f; //const Foo f; // workaround } const Foo foo = { 123 }; // line 11 const Bar bar = { f: foo // the problem is here }; --- bug.d(11): Error: cannot implicitly convert expression (Foo(123)) of type const(Foo) to Foo The problem here is that Bar.f is not const, while foo is. Since bar is const, shouldn't consts always be legal in the initializer? Or doesn't it work that way? The workaround for this is pretty simple, I know. foo could also be made an enum, but I need 1.x compatibility.Weird. With transitive const, I'd expect the assignment to be from const(Foo) to const(Foo). Sean
Jan 06 2008
Another surprise I got was when doing something like this: --- struct Bar { int f; } const Bar bar = { 5 }; void f(in Bar b) { Bar[3] array; array[0] = b; // line 10 //array[0] = *cast(Bar*)&b; // ugly workaround } void main() { f(bar); } --- bug2.d(10): Error: cannot implicitly convert expression (b) of type const(Bar) to Bar The problem here is that f's parameter has to be 'in' or 'const', otherwise bar can't be used as an argument to f. But a const Bar can't be assigned to an element of an array, since the elements cannot be const, or assigning to them would be disallowed. So I guess mixing const and mutable structs is no longer viable as of 2.009, they would have to be separate types. But I guess that's the way transitive const has to be. In this example, making bar an enum instead of a const would solve the issue, though. I'm only doing this because I'm looking for an 1.0 compatible way of declaring struct consts like bar. Maybe I should just remove const instead. Trying to cast away the constness of f's b argument doesn't work either. The compiler complains about a missing opCall when I do 'cast(Bar)b'. Is that bug, or is a different syntax for casting away const needed?
Jan 06 2008
You actually managed to make your programs compatible with D 1.x and 2.x !?!? I spent a good 40 minutes on my source, and ultimately realized it's impossible for me to do so; version(D_Version2) alias const(char)[] const_string; else alias char[] const_string; Value { const Value opIndex(const_string){ bla bla } } You can't alias out the const declaration for the function, and you can't get rid of it in 2.x and still have the program work, let alone have the desired functionality. Only reason the strings work is 'cause Alan showed me. : )
Jan 06 2008
Dan wrote:You actually managed to make your programs compatible with D 1.x and 2.x !?!?Only some bindings to a C library, so no classes or const methods necessary.I spent a good 40 minutes on my source, and ultimately realized it's impossible for me to do so; version(D_Version2) alias const(char)[] const_string; else alias char[] const_string; Value { const Value opIndex(const_string){ bla bla } } You can't alias out the const declaration for the function, and you can't get rid of it in 2.x and still have the program work, let alone have the desired functionality.Maybe you could make it work with some casting, but it might not be worth it. The const_string alias will work if you use a string mixin: version(D_Version2) mixin("alias const(char)[] const_string;"); else alias char[] const_string; But are you sure you need this, won't the Phobos string alias work? It's defined in object.d.
Jan 07 2008
torhu wrote:Dan wrote:And then you can just do: static if (!is(typeof(string))) alias char[] string; Future-proofs in case your code works with Tango and it gets a string alias in the future.You actually managed to make your programs compatible with D 1.x and 2.x !?!?Only some bindings to a C library, so no classes or const methods necessary.I spent a good 40 minutes on my source, and ultimately realized it's impossible for me to do so; version(D_Version2) alias const(char)[] const_string; else alias char[] const_string; Value { const Value opIndex(const_string){ bla bla } } You can't alias out the const declaration for the function, and you can't get rid of it in 2.x and still have the program work, let alone have the desired functionality.Maybe you could make it work with some casting, but it might not be worth it. The const_string alias will work if you use a string mixin: version(D_Version2) mixin("alias const(char)[] const_string;"); else alias char[] const_string; But are you sure you need this, won't the Phobos string alias work? It's defined in object.d.
Jan 07 2008
torhu wrote:Dan wrote:You don't need either one for the function parameter. Try this: ... opIndex( in char[] ) {} I've come to the conclusion that the string aliases are really of fairly little utility in D, since 'in' works just as well for specifying const behavior and is also 1.0 compatible. About the only place I've found myself using them for portable code is the return value of the toString routine, since there is no portable way to define a const return value other than an alias with string mixins, as above. SeanYou actually managed to make your programs compatible with D 1.x and 2.x !?!?Only some bindings to a C library, so no classes or const methods necessary.I spent a good 40 minutes on my source, and ultimately realized it's impossible for me to do so; version(D_Version2) alias const(char)[] const_string; else alias char[] const_string; Value { const Value opIndex(const_string){ bla bla } } You can't alias out the const declaration for the function, and you can't get rid of it in 2.x and still have the program work, let alone have the desired functionality.Maybe you could make it work with some casting, but it might not be worth it. The const_string alias will work if you use a string mixin: version(D_Version2) mixin("alias const(char)[] const_string;"); else alias char[] const_string; But are you sure you need this, won't the Phobos string alias work? It's defined in object.d.
Jan 07 2008