www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - immutable

reply Robert <robert.welin hotmail.com> writes:
Hello,
I have just recently started programming in D (a very pleasant experience so
far I must say), but when experimenting with the the immutable attribute I
discovered that the following code does not generate a compile time nor a
runtime error:

//Decalare immutable string
immutable char[] buf = "hello";

//Print the value of buf
writefln("buf = %s",buf);

//Change buf by using standard input
stdin.readln(buf);

//Print buf again
writefln("buf = %s",buf);


This is a bit confusing to be because I had assumed that immutable data really
would be immutable (without casting). Why does the code above work?

Cheers
Nilew
Jan 26 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 15:32:58 -0500, Robert <robert.welin hotmail.com>  
wrote:

 Hello,
 I have just recently started programming in D (a very pleasant  
 experience so
 far I must say), but when experimenting with the the immutable attribute  
 I
 discovered that the following code does not generate a compile time nor a
 runtime error:

 //Decalare immutable string
 immutable char[] buf = "hello";

 //Print the value of buf
 writefln("buf = %s",buf);

 //Change buf by using standard input
 stdin.readln(buf);

 //Print buf again
 writefln("buf = %s",buf);


 This is a bit confusing to be because I had assumed that immutable data  
 really
 would be immutable (without casting). Why does the code above work?

It shouldn't. I don't know where the bug is. Please file a bug with a complete program (with a main() function) here: http://d.puremagic.com/issues/enter_bug.cgi BTW, this has a segfault in Linux, so it's definitely trying to overwrite immutable data. -Steve
Jan 26 2011
next sibling parent reply Trass3r <un known.com> writes:
 BTW, this has a segfault in Linux, so it's definitely trying to  
 overwrite immutable data.

Does it also segfault with string buf?
Jan 26 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/26/11 6:24 PM, spir wrote:
 On 01/26/2011 10:21 PM, Steven Schveighoffer wrote:
 On Wed, 26 Jan 2011 16:13:41 -0500, Trass3r <un known.com> wrote:

 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer.

No I meant it doesn't alter buf's original content, i.e. "hello" Of course it modifies the array itself via ~= and thus takes it as a ref. Though it should use 'out' instead I think.

Then why not return the newly-created buffer? Why alter the buffer via a parameter? It makes no sense to me. Better API: char[] readln(); or if you want different char types: C[] readln(C = char)();

Yes, that's how I think readln's API should be. Is a buf version for repeated use? (I guess no, since input comes from a user?) Denis

There is an overload of readln that looks like that. Andrei
Jan 26 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 15:47:23 -0500, Trass3r <un known.com> wrote:

 BTW, this has a segfault in Linux, so it's definitely trying to  
 overwrite immutable data.

Does it also segfault with string buf?

No. Now I'm confused :) -Steve
Jan 26 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
 BTW, this has a segfault in Linux, so it's definitely trying to  
 overwrite immutable data.

Does it also segfault with string buf?

No. Now I'm confused :)

On Linux strings are put into some read-only space. I guess an immutable(char[]) also puts the pointer and length into that storage.
Jan 26 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
(readln only uses ~= on buf, it doesn't change the original string)
Jan 26 2011
prev sibling next sibling parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 01/26/2011 02:40 PM, Steven Schveighoffer wrote:
 On Wed, 26 Jan 2011 15:32:58 -0500, Robert <robert.welin hotmail.com>
 wrote:

 Hello,
 I have just recently started programming in D (a very pleasant
 experience so
 far I must say), but when experimenting with the the immutable
 attribute I
 discovered that the following code does not generate a compile time nor a
 runtime error:

 //Decalare immutable string
 immutable char[] buf = "hello";

 //Print the value of buf
 writefln("buf = %s",buf);

 //Change buf by using standard input
 stdin.readln(buf);

 //Print buf again
 writefln("buf = %s",buf);


 This is a bit confusing to be because I had assumed that immutable
 data really
 would be immutable (without casting). Why does the code above work?

It shouldn't. I don't know where the bug is. Please file a bug with a complete program (with a main() function) here: http://d.puremagic.com/issues/enter_bug.cgi BTW, this has a segfault in Linux, so it's definitely trying to overwrite immutable data. -Steve

I'd guess this is the problem: void badurk(C,E)(ref C[] x, E y){ x ~= y; } void main(string[] args){ immutable char[] buf = "hello"; static assert(is(typeof(buf) == immutable(char[]))); badurk(buf,'a'); //compiler: la la, this is okay! } OT: this function confuses me: size_t readln(C)(ref C[] buf, dchar terminator = '\n') if (isSomeChar!C) { static if (is(C == char)) { enforce(p && p.handle, "Attempt to read from an unopened file."); return readlnImpl(p.handle, buf, terminator); } else { // TODO: optimize this string s = readln(terminator); if (!s.length) return 0; buf.length = 0; foreach (wchar c; s) //// <----- (?!) { buf ~= c; } return buf.length; } }
Jan 26 2011
parent "Nick Sabalausky" <a a.a> writes:
"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in message 
news:ihq1pm$2d2v$1 digitalmars.com...
 OT: this function confuses me:

             string s = readln(terminator);
             foreach (wchar c; s)                      //// <----- (?!)

Automatically converts s from string to wstring and iterates over the wchars. It should be dchar, though, not wchar.
Jan 26 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 15:52:25 -0500, Trass3r <un known.com> wrote:

 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer. readln needs a serious redesign it looks like. -Steve
Jan 26 2011
prev sibling next sibling parent reply Robert <robert.welin hotmail.com> writes:
I didn't expect the code to run, hence my question. I tried it on OSX first
which
might have been the reason. Ran it on Ubuntu too and got the expected
segmentation
fault.

But thank you for the answer, I have filed the bug.

Robert
Jan 26 2011
parent Robert <robert.welin hotmail.com> writes:
Hopefully they will give it double the attention then ;)
Jan 26 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 16:12:58 -0500, Robert <robert.welin hotmail.com>  
wrote:

 I didn't expect the code to run, hence my question. I tried it on OSX  
 first which
 might have been the reason. Ran it on Ubuntu too and got the expected  
 segmentation
 fault.

The code shouldn't even compile. But the segfault is OS dependent (as you discovered). Windows also will not segfault. -Steve
Jan 26 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer.

No I meant it doesn't alter buf's original content, i.e. "hello" Of course it modifies the array itself via ~= and thus takes it as a ref. Though it should use 'out' instead I think.
Jan 26 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
 But thank you for the answer, I have filed the bug.

Rats, I've filed one too ;) http://d.puremagic.com/issues/show_bug.cgi?id=5492
Jan 26 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 16:13:41 -0500, Trass3r <un known.com> wrote:

 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer.

No I meant it doesn't alter buf's original content, i.e. "hello" Of course it modifies the array itself via ~= and thus takes it as a ref. Though it should use 'out' instead I think.

Then why not return the newly-created buffer? Why alter the buffer via a parameter? It makes no sense to me. Better API: char[] readln(); or if you want different char types: C[] readln(C = char)(); I think the original intent was for the code to overwrite the buffer, but it doesn't take into account the append improvements circa 2.041. -Steve
Jan 26 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 19:46:43 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/26/11 6:24 PM, spir wrote:
 On 01/26/2011 10:21 PM, Steven Schveighoffer wrote:
 On Wed, 26 Jan 2011 16:13:41 -0500, Trass3r <un known.com> wrote:

 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer.

No I meant it doesn't alter buf's original content, i.e. "hello" Of course it modifies the array itself via ~= and thus takes it as a ref. Though it should use 'out' instead I think.

Then why not return the newly-created buffer? Why alter the buffer via a parameter? It makes no sense to me. Better API: char[] readln(); or if you want different char types: C[] readln(C = char)();

Yes, that's how I think readln's API should be. Is a buf version for repeated use? (I guess no, since input comes from a user?) Denis

There is an overload of readln that looks like that.

Then is my hypothesis correct that readln is *supposed* to overwrite the buffer? It currently doesn't. -Steve
Jan 26 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
This is a serious bug.
http://d.puremagic.com/issues/show_bug.cgi?id=5492
Jan 26 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 01/26/2011 10:21 PM, Steven Schveighoffer wrote:
 On Wed, 26 Jan 2011 16:13:41 -0500, Trass3r <un known.com> wrote:

 (readln only uses ~= on buf, it doesn't change the original string)

What? Why does it take a ref argument then? If it doesn't overwrite the buffer passed in, there is no point in giving it a buffer.

No I meant it doesn't alter buf's original content, i.e. "hello" Of course it modifies the array itself via ~= and thus takes it as a ref. Though it should use 'out' instead I think.

Then why not return the newly-created buffer? Why alter the buffer via a parameter? It makes no sense to me. Better API: char[] readln(); or if you want different char types: C[] readln(C = char)();

Yes, that's how I think readln's API should be. Is a buf version for repeated use? (I guess no, since input comes from a user?) Denis -- _________________ vita es estrany spir.wikidot.com
Jan 26 2011
prev sibling parent Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Trass3r napisa=B3:

 But thank you for the answer, I have filed the bug.

Rats, I've filed one too ;) http://d.puremagic.com/issues/show_bug.cgi?id=3D5492

We found it over a year ago :) http://d.puremagic.com/issues/show_bug.cgi?id=3D3534 --=20 Tomek
Jan 27 2011