digitalmars.D - To dup or not to dup?
- =?ISO-8859-1?Q?J=FCrgen_Herz?= (15/15) Feb 25 2007 Hi,
- Johan Granberg (3/24) Feb 25 2007 You should not write to string literals but if the compiler enforces it ...
- Frits van Bommel (13/32) Feb 25 2007 Let me guess, you're running Windows. (checks post header) Yep.
- =?ISO-8859-1?Q?J=FCrgen_Herz?= (43/64) Feb 26 2007 That's right.
- Frits van Bommel (33/87) Feb 26 2007 With my Linux gcc it *does* crash:
- Lionello Lunesu (5/108) Feb 26 2007 Strange, from the DMD changelog:
- Frits van Bommel (3/23) Feb 26 2007 Because it's not constant enough to allow 'const', apparently. If you
- =?ISO-8859-1?Q?J=FCrgen_Herz?= (11/32) Feb 27 2007 Uh, sorry. I mixed up C and D and just wrote
- Saaa (5/7) Feb 26 2007 I don't :)
- Frits van Bommel (13/22) Feb 26 2007 A string literal directly references the memory it's stored in in the
Hi, I'm absolutely new to D and about to see if D is a language I could like. On http://www.digitalmars.com/d/cppstrings.html I found char[] s1 = "hello world"; char[] s2 = "goodbye ".dup; s2[8..13] = s1[6..11]; // s2 is "goodbye world" The .dup is needed because string literals are read-only in D, the .dup will create a copy that is writable. The same with char []a = "Txst"; a[1] = 'a'; I find that interesting because here it also works (compiles and runs) without .dup (DMD 1.007). Has the language changed since writing that web page? Jürgen
Feb 25 2007
Jürgen Herz wrote:Hi, I'm absolutely new to D and about to see if D is a language I could like. On http://www.digitalmars.com/d/cppstrings.html I found char[] s1 = "hello world"; char[] s2 = "goodbye ".dup; s2[8..13] = s1[6..11]; // s2 is "goodbye world" The .dup is needed because string literals are read-only in D, the .dup will create a copy that is writable. The same with char []a = "Txst"; a[1] = 'a'; I find that interesting because here it also works (compiles and runs) without .dup (DMD 1.007). Has the language changed since writing that web page? JürgenYou should not write to string literals but if the compiler enforces it or not is a quality of implementation issue.
Feb 25 2007
Jürgen Herz wrote:Hi, I'm absolutely new to D and about to see if D is a language I could like. On http://www.digitalmars.com/d/cppstrings.html I found char[] s1 = "hello world"; char[] s2 = "goodbye ".dup; s2[8..13] = s1[6..11]; // s2 is "goodbye world" The .dup is needed because string literals are read-only in D, the .dup will create a copy that is writable. The same with char []a = "Txst"; a[1] = 'a'; I find that interesting because here it also works (compiles and runs) without .dup (DMD 1.007). Has the language changed since writing that web page?Let me guess, you're running Windows. (checks post header) Yep. Segfaults for me (running Linux). This isn't enforced on Windows. I'm not sure whose fault that is, but I assume Microsoft :P. Before you think I'm a MS basher, I'd like to mention that IIRC it's not enforced for C either on Windows: if you initialize char* with a string literal and try to modify it -- which is illegal in C for the very same reason -- it won't complain. Just because it doesn't crash on your computer doesn't mean it's legal or that it'll work on every computer (or even on your computer with a different compiler, for that matter -- though in this case it probably will if it's because of Windows).
Feb 25 2007
Frits van Bommel wrote:Jürgen Herz wrote:That's right. I've now also set up dmd on Linux and it segfaults here too.The same with char []a = "Txst"; a[1] = 'a'; I find that interesting because here it also works (compiles and runs) without .dup (DMD 1.007). Has the language changed since writing that web page?Let me guess, you're running Windows. (checks post header) Yep. Segfaults for me (running Linux).This isn't enforced on Windows. I'm not sure whose fault that is, but I assume Microsoft :P. Before you think I'm a MS basher, I'd like to mention that IIRC it's not enforced for C either on Windows: if you initialize char* with a string literal and try to modify it -- which is illegal in C for the very same reason -- it won't complain.It also isn't enforced for C on Linux (gcc) though it also doesn't crash. Anyways, that's C and D (resp. dmd) could do better.Just because it doesn't crash on your computer doesn't mean it's legal or that it'll work on every computer (or even on your computer with a different compiler, for that matter -- though in this case it probably will if it's because of Windows).I understand that it is and why it is illegal. And crashing on Linux I'm relieved seeing the "right" consequence of doing illegal things. But I'm not convinced of the compiler. In my point of view a language and a compiler should catch as many programming errors at the earliest point possible, that is at compile time. What I started with was to find out if there's a const in D. Well, it is but ... To me it looks very inconsequent: char []a = "Test"; a[1] = 'x'; segfaults while const char []a = "Test"; a[1] = 'x'; is caught at compile time with "Error: string literals are immutable". Interestingly const char []a = "Test"; a[1..2] = "x"; compiles without warnings though still segfaults. Even worse: const char []a = "Test"; test(a); void test(char []s) { s[1] = 'x'; } Not only there doesn't seem no way to declare a function argument const, a non-const argument removes const without warnings - and promptly segfaults in test. On windows the result of that code is very interesting. Since it doesn't segfault, one can printf a and s after manipulation. And it's "Txst" in test() and "Test" outside. BTW const char []a = "Test".dup; gives consttest.d(3): Error: cannot evaluate _adDupT(&_D12TypeInfo_G4a6__initZ,"Test") at compile time. What does in want to tell me? Jürgen
Feb 26 2007
Jürgen Herz wrote:Frits van Bommel wrote:With my Linux gcc it *does* crash: --- urxae urxae:~/tmp$ cat test.c int main() { char* str = "test"; str[0] = 'b'; } urxae urxae:~/tmp$ gcc test.c -o test urxae urxae:~/tmp$ ./test Segmentation fault (core dumped) --- Though it isn't enforced by the compiler.This isn't enforced on Windows. I'm not sure whose fault that is, but I assume Microsoft :P. Before you think I'm a MS basher, I'd like to mention that IIRC it's not enforced for C either on Windows: if you initialize char* with a string literal and try to modify it -- which is illegal in C for the very same reason -- it won't complain.It also isn't enforced for C on Linux (gcc) though it also doesn't crash. Anyways, that's C and D (resp. dmd) could do better.Indeed.Just because it doesn't crash on your computer doesn't mean it's legal or that it'll work on every computer (or even on your computer with a different compiler, for that matter -- though in this case it probably will if it's because of Windows).I understand that it is and why it is illegal. And crashing on Linux I'm relieved seeing the "right" consequence of doing illegal things.But I'm not convinced of the compiler. In my point of view a language and a compiler should catch as many programming errors at the earliest point possible, that is at compile time.Yes, this is usually a good idea.What I started with was to find out if there's a const in D. Well, it is but ...There are plans to add a better concept of non-modifiability to D, but last I heard Walter and Andrei are still working out the details of how it will work.To me it looks very inconsequent: char []a = "Test"; a[1] = 'x'; segfaults while const char []a = "Test"; a[1] = 'x'; is caught at compile time with "Error: string literals are immutable". Interestingly const char []a = "Test"; a[1..2] = "x"; compiles without warnings though still segfaults.Current const support is indeed a bit weak.Even worse: const char []a = "Test"; test(a); void test(char []s) { s[1] = 'x'; } Not only there doesn't seem no way to declare a function argument const, a non-const argument removes const without warnings - and promptly segfaults in test.This is one of the issues that should be addressed by the changes I mentioned above.On windows the result of that code is very interesting. Since it doesn't segfault, one can printf a and s after manipulation. And it's "Txst" in test() and "Test" outside.Yes, it allows it to be modified, which is why it doesn't crash. I'm not sure why this is, but my guess is that either PE (the file format of Windows executables) doesn't allow you to specify "this part should be in read-only memory" or Windows doesn't follow those directions. I *do* know that ELF (the typical format of Linux executables) allows you to specify that and it is enforced when possible (i.e. when possible on the processor, which means "if everything on that memory page is read-only" on x86 processors)BTW const char []a = "Test".dup; gives consttest.d(3): Error: cannot evaluate _adDupT(&_D12TypeInfo_G4a6__initZ,"Test") at compile time. What does in want to tell me?It wants to tell you that the result of '"Test".dup' cannot be evaluated at compile time. In some cases, 'const' really _means_ constant in D, the value needs to be available at compile time (or actually at link time in many cases).
Feb 26 2007
Frits van Bommel wrote:Jürgen Herz wrote:Strange, from the DMD changelog: * The .dup property is now allowed for compile time function execution. Why is it complaining for that .dup? L.Frits van Bommel wrote:With my Linux gcc it *does* crash: --- urxae urxae:~/tmp$ cat test.c int main() { char* str = "test"; str[0] = 'b'; } urxae urxae:~/tmp$ gcc test.c -o test urxae urxae:~/tmp$ ./test Segmentation fault (core dumped) --- Though it isn't enforced by the compiler.This isn't enforced on Windows. I'm not sure whose fault that is, but I assume Microsoft :P. Before you think I'm a MS basher, I'd like to mention that IIRC it's not enforced for C either on Windows: if you initialize char* with a string literal and try to modify it -- which is illegal in C for the very same reason -- it won't complain.It also isn't enforced for C on Linux (gcc) though it also doesn't crash. Anyways, that's C and D (resp. dmd) could do better.Indeed.Just because it doesn't crash on your computer doesn't mean it's legal or that it'll work on every computer (or even on your computer with a different compiler, for that matter -- though in this case it probably will if it's because of Windows).I understand that it is and why it is illegal. And crashing on Linux I'm relieved seeing the "right" consequence of doing illegal things.But I'm not convinced of the compiler. In my point of view a language and a compiler should catch as many programming errors at the earliest point possible, that is at compile time.Yes, this is usually a good idea.What I started with was to find out if there's a const in D. Well, it is but ...There are plans to add a better concept of non-modifiability to D, but last I heard Walter and Andrei are still working out the details of how it will work.To me it looks very inconsequent: char []a = "Test"; a[1] = 'x'; segfaults while const char []a = "Test"; a[1] = 'x'; is caught at compile time with "Error: string literals are immutable". Interestingly const char []a = "Test"; a[1..2] = "x"; compiles without warnings though still segfaults.Current const support is indeed a bit weak.Even worse: const char []a = "Test"; test(a); void test(char []s) { s[1] = 'x'; } Not only there doesn't seem no way to declare a function argument const, a non-const argument removes const without warnings - and promptly segfaults in test.This is one of the issues that should be addressed by the changes I mentioned above.On windows the result of that code is very interesting. Since it doesn't segfault, one can printf a and s after manipulation. And it's "Txst" in test() and "Test" outside.Yes, it allows it to be modified, which is why it doesn't crash. I'm not sure why this is, but my guess is that either PE (the file format of Windows executables) doesn't allow you to specify "this part should be in read-only memory" or Windows doesn't follow those directions. I *do* know that ELF (the typical format of Linux executables) allows you to specify that and it is enforced when possible (i.e. when possible on the processor, which means "if everything on that memory page is read-only" on x86 processors)BTW const char []a = "Test".dup; gives consttest.d(3): Error: cannot evaluate _adDupT(&_D12TypeInfo_G4a6__initZ,"Test") at compile time. What does in want to tell me?It wants to tell you that the result of '"Test".dup' cannot be evaluated at compile time. In some cases, 'const' really _means_ constant in D, the value needs to be available at compile time (or actually at link time in many cases).
Feb 26 2007
Lionello Lunesu wrote:Frits van Bommel wrote:Because it's not constant enough to allow 'const', apparently. If you remove the 'const' it works just fine.Jürgen Herz wrote:Strange, from the DMD changelog: * The .dup property is now allowed for compile time function execution. Why is it complaining for that .dup?BTW const char []a = "Test".dup; gives consttest.d(3): Error: cannot evaluate _adDupT(&_D12TypeInfo_G4a6__initZ,"Test") at compile time. What does in want to tell me?It wants to tell you that the result of '"Test".dup' cannot be evaluated at compile time. In some cases, 'const' really _means_ constant in D, the value needs to be available at compile time (or actually at link time in many cases).
Feb 26 2007
Frits van Bommel wrote:Jürgen Herz wrote:Uh, sorry. I mixed up C and D and just wrote char a[] = "Test"; in the C test. That's different from []a on D of course.It also isn't enforced for C on Linux (gcc) though it also doesn't crash. Anyways, that's C and D (resp. dmd) could do better.With my Linux gcc it *does* crash: --- urxae urxae:~/tmp$ cat test.c int main() { char* str = "test"; str[0] = 'b'; } urxae urxae:~/tmp$ gcc test.c -o test urxae urxae:~/tmp$ ./test Segmentation fault (core dumped) ---There are plans to add a better concept of non-modifiability to D,Having a 1.0 I was under the impression such basics would have been done. But if it's not I'm glad to hear it's worked on.Yes, but what I'm surprised is that s and a seem to point to different memory (seem because I didn't look at the actual addresses - have to make up for that when on Win again) since the string a was unchanged even after s was changed in test(). JürgenYes, it allows it to be modified, which is why it doesn't crash.On windows the result of that code is very interesting. Since it doesn't segfault, one can printf a and s after manipulation. And it's "Txst" in test() and "Test" outside.
Feb 27 2007
I understand that it is and why it is illegal. And crashing on Linux I'm relieved seeing the "right" consequence of doing illegal things.I don't :) Could anybody pls explain it? What is wrong with changing a part of an array? or better, what is the difference between a string literal and an array of chars?
Feb 26 2007
Saaa wrote:A string literal directly references the memory it's stored in in the loaded executable. That same piece of memory can be used by every reference to that string literal. So something like: --- void main() { char[] test = "Hi"; test[1] = 'o'; writefln("%s", "Hi"); } --- may print "Ho" if the string is allowed to be modified. That's also dependent on how well the compiler optimizes this stuff, though.I understand that it is and why it is illegal. And crashing on Linux I'm relieved seeing the "right" consequence of doing illegal things.I don't :) Could anybody pls explain it? What is wrong with changing a part of an array? or better, what is the difference between a string literal and an array of chars?
Feb 26 2007