digitalmars.D.learn - immutable string literal?
- strtr (11/11) Feb 21 2010 On winXP (D1) I can compile/run this code without a problem.
- Daniel Keep (4/17) Feb 21 2010 There's no compiler error because D1 doesn't have a const/immutable syst...
- strtr (3/23) Feb 22 2010 But according to the specs, it does constitute an error and I suspect st...
- Steven Schveighoffer (30/55) Feb 22 2010 Yes, it is possible -- use D2 which has such errors :) Without a const ...
- strtr (4/71) Feb 22 2010 Thanks, I understand.
- Steven Schveighoffer (9/12) Feb 22 2010 A segfault is a runtime error. The problem with Windows is it doesn't
- grauzone (4/19) Feb 22 2010 Windows can protect memory as read-only too. Why dmd doesn't do that is
- strtr (2/7) Feb 22 2010 If that is the case, then I'd suggest a(n enhancement?) bug-report :)
- Steven Schveighoffer (11/26) Feb 22 2010 I'm not super-familiar with windows capabilities, but I'd venture a gues...
- strtr (2/11) Feb 22 2010 The point is that I didn't know the char array literal to be immutable. ...
- Steven Schveighoffer (9/26) Feb 22 2010 As I said before, it's not possible for the compiler to check this. It'...
On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= "immutable literal?"; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier.
Feb 21 2010
strtr wrote:On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= "immutable literal?"; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier.There's no compiler error because D1 doesn't have a const/immutable system. There's no crash because Windows doesn't write-protect the data segment which contains the literal.
Feb 21 2010
Daniel Keep Wrote:strtr wrote:But according to the specs, it does constitute an error and I suspect string literals are placed in a specific memory location. Wouldn't it be possible to error on such code?On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= "immutable literal?"; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier.There's no compiler error because D1 doesn't have a const/immutable system. There's no crash because Windows doesn't write-protect the data segment which contains the literal.
Feb 22 2010
On Mon, 22 Feb 2010 08:32:20 -0500, strtr <strtr spam.com> wrote:Daniel Keep Wrote:Yes, it is possible -- use D2 which has such errors :) Without a const system, D1 cannot distinguish between char[] that originated from a literal (i.e. in the static data segment) or which originated from the heap. At the point where you see the line: s[$-1] = '!'; You don't have the entire history of where s came from. It can be even harder to detect than you think. For instance, should you allow the following code to compile? int main(char[][] args) { char[] s; if(args[1] == "y") s = "immutable literal?"; else s = "mutable literal?".dup; s[$-1] = "!"; return 0; } This program runs fine unless you pass the exact argument 'y' to the program, and then it crashes. How does the compiler know at the line where s is modified that it could have possibly come from a literal? If you still think it's possible, what about this? void exclaim(char[] s) { s[$-1] = '!'; } If this is in its own module, how can the compiler tell whether s is immutable or not? -Stevestrtr wrote:But according to the specs, it does constitute an error and I suspect string literals are placed in a specific memory location. Wouldn't it be possible to error on such code?On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= "immutable literal?"; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier.There's no compiler error because D1 doesn't have a const/immutable system. There's no crash because Windows doesn't write-protect the data segment which contains the literal.
Feb 22 2010
Steven Schveighoffer Wrote:On Mon, 22 Feb 2010 08:32:20 -0500, strtr <strtr spam.com> wrote:Thanks, I understand. But, how about a runtime error? Isn't a literal placed in easy to identify should-only-read memory?Daniel Keep Wrote:Yes, it is possible -- use D2 which has such errors :) Without a const system, D1 cannot distinguish between char[] that originated from a literal (i.e. in the static data segment) or which originated from the heap. At the point where you see the line: s[$-1] = '!'; You don't have the entire history of where s came from. It can be even harder to detect than you think. For instance, should you allow the following code to compile? int main(char[][] args) { char[] s; if(args[1] == "y") s = "immutable literal?"; else s = "mutable literal?".dup; s[$-1] = "!"; return 0; } This program runs fine unless you pass the exact argument 'y' to the program, and then it crashes. How does the compiler know at the line where s is modified that it could have possibly come from a literal? If you still think it's possible, what about this? void exclaim(char[] s) { s[$-1] = '!'; } If this is in its own module, how can the compiler tell whether s is immutable or not? -Stevestrtr wrote:But according to the specs, it does constitute an error and I suspect string literals are placed in a specific memory location. Wouldn't it be possible to error on such code?On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= "immutable literal?"; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier.There's no compiler error because D1 doesn't have a const/immutable system. There's no crash because Windows doesn't write-protect the data segment which contains the literal.
Feb 22 2010
On Mon, 22 Feb 2010 09:27:57 -0500, strtr <strtr spam.com> wrote:Thanks, I understand. But, how about a runtime error? Isn't a literal placed in easy to identify should-only-read memory?A segfault is a runtime error. The problem with Windows is it doesn't throw an error on writes to its data segment (unlike Linux). In reality, the result of your program is undefined, so don't expect any help from the compiler/runtime. There's nothing D1 can do about that. In order for D to intercept that, it would have to instrument every write to memory, and that would cause performance problems like you wouldn't believe. The short answer: Just don't do that. -Steve
Feb 22 2010
Steven Schveighoffer wrote:On Mon, 22 Feb 2010 09:27:57 -0500, strtr <strtr spam.com> wrote:Windows can protect memory as read-only too. Why dmd doesn't do that is a mystery. Even if .exe doesn't support read-only data segments, the runtime could have done so in early start-up code.Thanks, I understand. But, how about a runtime error? Isn't a literal placed in easy to identify should-only-read memory?A segfault is a runtime error. The problem with Windows is it doesn't throw an error on writes to its data segment (unlike Linux). In reality, the result of your program is undefined, so don't expect any help from the compiler/runtime. There's nothing D1 can do about that. In order for D to intercept that, it would have to instrument every write to memory, and that would cause performance problems like you wouldn't believe.The short answer: Just don't do that. -Steve
Feb 22 2010
grauzone Wrote:Windows can protect memory as read-only too. Why dmd doesn't do that is a mystery. Even if .exe doesn't support read-only data segments, the runtime could have done so in early start-up code.If that is the case, then I'd suggest a(n enhancement?) bug-report :)
Feb 22 2010
On Mon, 22 Feb 2010 10:19:52 -0500, grauzone <none example.net> wrote:Steven Schveighoffer wrote:I'm not super-familiar with windows capabilities, but I'd venture a guess that doing so would make exe's not compatible with older versions of Windows. But still, what does it matter? Just don't use D1 if you want a compiler error, or don't try and trick the system into modifying ROM! There are plenty of projects using D1 that just don't do this, and they are fine. Implementing features to help people determine they created undefined behavior is simply a waste of time. If you feel you can fix it, by all means submit a patch, and it might get in. -SteveOn Mon, 22 Feb 2010 09:27:57 -0500, strtr <strtr spam.com> wrote:Windows can protect memory as read-only too. Why dmd doesn't do that is a mystery. Even if .exe doesn't support read-only data segments, the runtime could have done so in early start-up code.Thanks, I understand. But, how about a runtime error? Isn't a literal placed in easy to identify should-only-read memory?A segfault is a runtime error. The problem with Windows is it doesn't throw an error on writes to its data segment (unlike Linux). In reality, the result of your program is undefined, so don't expect any help from the compiler/runtime. There's nothing D1 can do about that. In order for D to intercept that, it would have to instrument every write to memory, and that would cause performance problems like you wouldn't believe.
Feb 22 2010
Steven Schveighoffer Wrote:But still, what does it matter? Just don't use D1 if you want a compiler error, or don't try and trick the system into modifying ROM! There are plenty of projects using D1 that just don't do this, and they are fine. Implementing features to help people determine they created undefined behavior is simply a waste of time. If you feel you can fix it, by all means submit a patch, and it might get in. -SteveThe point is that I didn't know the char array literal to be immutable. I thought it would be like any other array literal. Now I get to recheck my whole project to see whether I ever change an immutable array. "Use D2" is not really an argument in this case as I didn't even know I was using a "trick". For me it would have been great if the compiler would have segfaulted on this undefined behaviour.
Feb 22 2010
On Mon, 22 Feb 2010 11:24:36 -0500, strtr <strtr spam.com> wrote:Steven Schveighoffer Wrote:As I said before, it's not possible for the compiler to check this. It's unfortunate that array literals are treated differently than strings, and perhaps more unfortunate that Windows doesn't throw a loud error when this occurs. I don't see any way to "fix" that, because D1's spec is frozen. The crappy answer is, you'll just have to live with it. On the bright side, after frustratingly having to examine your code again for this problem, you are less likely to make this mistake in the future :) -SteveBut still, what does it matter? Just don't use D1 if you want a compiler error, or don't try and trick the system into modifying ROM! There are plenty of projects using D1 that just don't do this, and they are fine. Implementing features to help people determine they created undefined behavior is simply a waste of time. If you feel you can fix it, by all means submit a patch, and it might get in. -SteveThe point is that I didn't know the char array literal to be immutable. I thought it would be like any other array literal. Now I get to recheck my whole project to see whether I ever change an immutable array. "Use D2" is not really an argument in this case as I didn't even know I was using a "trick". For me it would have been great if the compiler would have segfaulted on this undefined behaviour.
Feb 22 2010