Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
September 09, 2007 Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
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? |
September 09, 2007 Re: Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | 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 |
September 10, 2007 Re: Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander | 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;
}
}
---
|
September 10, 2007 Re: Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | "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. |
September 10, 2007 Re: Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | 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
}
}
---
|
September 10, 2007 Re: Cannot call mutable method on final struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | 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 |
Copyright © 1999-2021 by the D Language Foundation