Comment #0 by bearophile_hugs — 2010-07-31T04:26:35Z
dmd 2.047 compiles this code, but string literals can't be lvalues:
void main() {
"hello" = "red";
}
Comment #1 by andrej.mitrovich — 2010-07-31T07:27:57Z
I just found this by accident on the compiler docs page:
http://www.digitalmars.com/d/2.0/dmd-windows.html
"
Differences between Windows and Linux versions
* String literals are read-only under Linux. Attempting to write to them will cause a segment violation.
"
Maybe this is relevant?
Comment #2 by bearophile_hugs — 2010-07-31T08:48:12Z
I think that's not relevant, I think that refers to changing the content of a variable initialized with a string literal (plus cast to mutable).
But the code I have shown is meaningless, because a string can't be a lvalue. It's like doing:
void main() {
5 = 7;
}
Comment #3 by andrej.mitrovich — 2010-07-31T09:18:53Z
Yeah, it does not make sense at all. But it gets worse:
import std.stdio;
void main() {
"hello" = "red";
string x = "hello";
writeln(x);
}
Writes "red"
That's not good. :)
Comment #4 by clugdbug — 2010-07-31T17:30:23Z
(In reply to comment #3)
> Yeah, it does not make sense at all. But it gets worse:
>
> import std.stdio;
>
> void main() {
> "hello" = "red";
> string x = "hello";
> writeln(x);
> }
>
> Writes "red"
>
> That's not good. :)
Ouch!
Comment #5 by nfxjfg — 2010-07-31T18:43:05Z
This segfaults on the far superior Linux (dmd v2.046), so yes, it's probably because OPTLINK can't do read-only sections.
Comment #6 by bearophile_hugs — 2010-10-29T09:55:19Z
A related bug found by denis spir:
auto p = &"hello";
String literals aren't lvalues, so you can't take their address. Just as you can't tale the address of a decimal literal:
auto q = &(1);
I think the main problem is that dmd treats string literal as lvalue.
Lvalue can appear on left hand side of assignment, so string literal now asignable.
Patch comment #7 fixes this behavior, and this change also refuse string literal on ref parameter as a side effect.
It seems to me that it is correct refusing string literal on ref parameter.
So this change breaks existing code.
(If D specification treats string literal specially, my think is mistaken.
But it might be not.)
Comment #17 by bearophile_hugs — 2012-01-29T14:36:02Z
With the latest DMD2.058head this code:
void foo(immutable ref string) {}
void main() {
foo("hello");
}
Gives:
test.d(3): Error: function test.foo (ref immutable(char[]) _param_0) is not callable using argument types (string)
Is this expected?
(Also note the function signature is (ref immutable(char[]) _param_0) while I have specified an immutable ref).
Comment #18 by k.hara.pg — 2012-01-29T15:20:53Z
(In reply to comment #17)
> With the latest DMD2.058head this code:
>
>
> void foo(immutable ref string) {}
> void main() {
> foo("hello");
> }
>
>
> Gives:
>
> test.d(3): Error: function test.foo (ref immutable(char[]) _param_0) is not
> callable using argument types (string)
>
> Is this expected?
>
> (Also note the function signature is (ref immutable(char[]) _param_0) while I
> have specified an immutable ref).
Yes, it is expected behavior.
'ref' storage class requires lvalue slice in this case, but string literal DOESN'T have slice, because it has only content.
Instead, you can get a reference to string literal by `ref immutable(char[5])` or `ref const(char[5])` (5 == "hello".length), they bind just only content.
Comment #19 by andrej.mitrovich — 2012-01-29T20:51:39Z
(In reply to comment #17)
> void foo(immutable ref string) {}
I'm curious, what does `immutable ref string` buy you compared to just immutable string? Can't the compiler pass by ref automatically if it's an immutable type?
Comment #20 by bearophile_hugs — 2012-01-31T17:09:46Z
(In reply to comment #18)
> Yes, it is expected behavior.
I have just seen that some of my code that used to compile now gives a problem. This is a reduced version:
void foo(ref string t) {}
void main() {
immutable string s;
foo(s);
}
DMD 2.058head gives:
test.d(4): Error: function test.foo (ref string t) is not callable using argument types (immutable(char[]))
Is this correct?
Comment #21 by bearophile_hugs — 2012-01-31T17:24:32Z
(In reply to comment #20)
> Is this correct?
Yes, it's correct, sorry.