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









"Jarrett Billingsley" <kb3ctd2 yahoo.com> 