digitalmars.D.learn - Cannot call mutable method on final struct
- Christopher Wright <dhasenan gmail.com> Sep 09 2007
- Carlos Santander <csantander619 gmail.com> Sep 09 2007
- Christopher Wright <dhasenan gmail.com> Sep 10 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Sep 10 2007
- Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> Sep 10 2007
- Carlos Santander <csantander619 gmail.com> Sep 10 2007
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: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; } } ---
In that case, I guess the workaround (ref b) is not really a workaround but the way it should be done. -- Carlos Santander Bernal
Sep 10 2007









"Jarrett Billingsley" <kb3ctd2 yahoo.com> 