digitalmars.D.learn - Cannot call mutable method on final struct
- Christopher Wright (28/28) Sep 09 2007 Hey everyone.
- Carlos Santander (7/42) Sep 09 2007 I don't use D 2.0, but here it goes...
- Christopher Wright (16/22) Sep 10 2007 If I use char[] rather than string, it fails with the error message I
- Jarrett Billingsley (7/9) Sep 10 2007 Iiii wouldn't be so sure about that. I don't know if the compiler rewri...
- Christian Kamm (22/31) Sep 10 2007 The problem is that the b defined in the foreach statement is final, thu...
- Carlos Santander (5/30) Sep 10 2007 In that case, I guess the workaround (ref b) is not really a workaround ...
Hey everyone. I get an error on the following code complaining about the use of Box.toString. The message is: "Error: cannot call mutable method on final struct" I don't know what that means. I believe it's complaining about const stuff and the struct being altered (that is all that makes sense, given the message and the fact that it's in a loop), but looking at the toString method in std.boxer.Box, it doesn't seem to alter the struct. As far as I can tell, the code should be valid. The workaround is using 'ref Box b' (or 'ref b') in the foreach loop. --- import std.boxer, std.string, std.stdio; class C(U...) { string value; this (U u) { value = ""; foreach (Box b; boxArray(u)) { value ~= b.toString; } } } void main () { auto c = new C!(int, string, char)(12, "foom", 't'); writefln(c.value); } --- Can anyone here else say whether this is a bug in Box.toString or in determining whether a function is mutable?
Sep 09 2007
Christopher Wright escribió:Hey everyone. I get an error on the following code complaining about the use of Box.toString. The message is: "Error: cannot call mutable method on final struct" I don't know what that means. I believe it's complaining about const stuff and the struct being altered (that is all that makes sense, given the message and the fact that it's in a loop), but looking at the toString method in std.boxer.Box, it doesn't seem to alter the struct. As far as I can tell, the code should be valid. The workaround is using 'ref Box b' (or 'ref b') in the foreach loop. --- import std.boxer, std.string, std.stdio; class C(U...) { string value; this (U u) { value = ""; foreach (Box b; boxArray(u)) { value ~= b.toString; } } } void main () { auto c = new C!(int, string, char)(12, "foom", 't'); writefln(c.value); } --- Can anyone here else say whether this is a bug in Box.toString or in determining whether a function is mutable?I don't use D 2.0, but here it goes... string is const(char)[] or const char[] or something like that... It's const, anyway, so you aren't supposed to modify it. Replace "string value" with "char[] value". -- Carlos Santander Bernal
Sep 09 2007
Carlos Santander wrote:I don't use D 2.0, but here it goes... string is const(char)[] or const char[] or something like that... It's const, anyway, so you aren't supposed to modify it. Replace "string value" with "char[] value".If I use char[] rather than string, it fails with the error message I stated (and indeed, in the original, I used char[] accidentally). If I just call Box.toString and don't do anything with the returned string, it fails with the same error message. 'string ~= whatever' is valid because the string is not final. The compiler rewrites it as 'string = string ~ whatever'. New minimal test case: --- import std.boxer; void main () { foreach (b; boxArray(9, 'b')) { b.toString; } } ---
Sep 10 2007
"Christopher Wright" <dhasenan gmail.com> wrote in message news:fc3bdu$8tn$1 digitalmars.com...'string ~= whatever' is valid because the string is not final. The compiler rewrites it as 'string = string ~ whatever'.Iiii wouldn't be so sure about that. I don't know if the compiler rewrites "a ~= b" as "a = a ~ b" when dealing with const stuff, but as far as D1 goes, ~= and ~ are two different operations. ~ always creates a copy of the original data, while ~= attempts to resize the destination in place and append the new data in the newly-resized space.
Sep 10 2007
Christopher Wright wrote:New minimal test case: --- import std.boxer; void main () { foreach (b; boxArray(9, 'b')) { b.toString; } } ---The problem is that the b defined in the foreach statement is final, thus D won't let you call non-const methods on it. Boxer.toString is not a const method. Same thing without boxer or toString: --- struct Foo { const void const_bar() {} void nonconst_bar() {} } void main() { Foo[] foo_arr; foo_arr.length = 1; foreach(foo; foo_arr) { foo.const_bar(); // OK foo.nonconst_bar(); // Error: cannot call mutable method on final struct } } ---
Sep 10 2007
Christopher Wright escribió:Carlos Santander wrote:In that case, I guess the workaround (ref b) is not really a workaround but the way it should be done. -- Carlos Santander BernalI don't use D 2.0, but here it goes... string is const(char)[] or const char[] or something like that... It's const, anyway, so you aren't supposed to modify it. Replace "string value" with "char[] value".If I use char[] rather than string, it fails with the error message I stated (and indeed, in the original, I used char[] accidentally). If I just call Box.toString and don't do anything with the returned string, it fails with the same error message. 'string ~= whatever' is valid because the string is not final. The compiler rewrites it as 'string = string ~ whatever'. New minimal test case: --- import std.boxer; void main () { foreach (b; boxArray(9, 'b')) { b.toString; } } ---
Sep 10 2007