January 14, 2008
Will this work as well?int[] def = [ 1, 2, 3 ];def[0]=0;int[] def2 = [ 1, 2, 3 ];assert(def2[0..2] == [ 0, 2, 3 ]);
> to compile, then you are free to modify the constant "text"!  For example, in D 1.0 this works:
>
> char[] text = "text";
> text[0] = 'n';
> char[] text2 = "text";
> assert(text2 == "next");
>
> These kinds of errors are subtle and hard to find.  This is why you are not allowed to have a non-const or invariant pointer to invariant data such as string literals.
>
> -Steve
> 


January 14, 2008
:)> Will this work as well?
int[] def = [ 1, 2, 3 ];
def[0]=0;
int[] def2 = [ 1, 2, 3 ];
assert(def2[0..2] == [ 0, 2, 3 ]);

>> to compile, then you are free to modify the constant "text"!  For example, in D 1.0 this works:
>>
>> char[] text = "text";
>> text[0] = 'n';
>> char[] text2 = "text";
>> assert(text2 == "next");
>>
>> These kinds of errors are subtle and hard to find.  This is why you are not allowed to have a non-const or invariant pointer to invariant data such as string literals.
>>
>> -Steve
>>
>
> 


January 14, 2008
"Bill Baxter" wrote
> Walter Bright wrote:
>> Neil Vice wrote:
>>> Firstly the following simple initialiser fails to compile:
>>>
>>>     char[] text = "text";
>>>
>>> As far as I can tell there is no way to declare and initialise an array in a single line of code
>>
>>     string text = "text";
>
> My intuition is that an implicit dup should happen.
> Why?  Well, maybe it's just familiarity with C++?
>
>   std::string text = "hello"; // makes a copy
>   text[0] = 'b'; // ok because we have a copy
>
> --bb

If assigning one string to another made a copy, you lose all the performance benefits of slicing.  If I make 20 "copies" of the same string, as long as the string is invariant, there is no reason that I need to keep 20 copies of it in memory.

That being said, let's examine the following line:

char[] text = "hello";

The compiler could interpret this 2 ways.  One is "yes, compiler, I know that "hello" is invariant, I just want a mutable copy of it", The other is "oops, I really meant to get a read-only pointer to that string data, so give me an error".

If the compiler interprets the first way, the coder who wants a read-only pointer isn't warned that he now has used inefficient heap memory.  If the compiler inteprets the second way, the coder who wants a copy is told he cannot do it that way, he fixes it, and now everyone is happy.

I like the way it works now.  Err on the side of clarity and efficiency.

-Steve


January 14, 2008
My intuition tells me that a char[] is an array of chars, just like int[] is
an array of ints.
If you want something special like a string literal you can use string or
stringl or something alike.


void function(in out int i){}

> :)> Will this work as well?
> int[] def = [ 1, 2, 3 ];
> def[0]=0;
> int[] def2 = [ 1, 2, 3 ];
> assert(def2[0..2] == [ 0, 2, 3 ]);
>
>>> to compile, then you are free to modify the constant "text"!  For example, in D 1.0 this works:
>>>
>>> char[] text = "text";
>>> text[0] = 'n';
>>> char[] text2 = "text";
>>> assert(text2 == "next");
>>>
>>> These kinds of errors are subtle and hard to find.  This is why you are not allowed to have a non-const or invariant pointer to invariant data such as string literals.
>>>
>>> -Steve
>>>
>>
>>
>
> 


January 14, 2008
Michiel Helvensteijn wrote:
> Yigal Chripun wrote:
> 
>>> But wouldn't the expected behavior be to implicitly duplicate the string
>>> literal? Or better yet, to never actually allocate memory for the string
>>> literal at all, but simply use it to set the initial value of the
>>> variable?
>> you're quite right, and on some OSes (Linux) no memory is allocated (on
>> the heap/stack) but rather the value is store in ROM.
>> however, char[] is an array which means you could have done the following:
>> char[] a = "abc";
>> a[1] = 'd';
>> which would segfault because you're changing something in ROM!
>> that's why the type of string literals is variant(char)[] or string for
>> short, and the above behavior is disallowed.
> 
> But wouldn't you want that to work exactly as written?
> 
> char[] str = "abc";
> a[1] = 'd';
> assert(str == "adc");
> 
> "abc" here is just the initial value of the mutable variable str. So it
> should be allocated in the memory pointed to by str.
> 
> In other words, an implicit cast should take place, or an implicit
> duplication should be made.
> 
> That it doesn't work like that is, in my opinion, a flaw of the language. D
> seems to continually get more difficult to use.
> 
to asnswer your question: no.
an important principle of D is COW (copy on write).
everywhere in D where you need a copy, you explicitly state that with a dup method or if you need to allocate memory for an object you use:
---
auto variable = new Type(params); // for example..
---
an implicit cast is a semantic error: the D spec says that an invariant cannot be cast implicitly to mutable, one of the reasons is because the compiler uses invariant to optimize code, another is the fact the invariant mean "nobody will change that object" and if you cast to mutable undefined behavior follows. meaning that a cast to mutable breaks the meaning of invariant.

an implicit duplication is also wrong: just read Steven's explanation in this thread.
1 2
Next ›   Last »