www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question about wchar[]

reply ollie <ollie home.net> writes:
I am using wchar[] and find the usage clunky. Am I doing something wrong?

Example:
    // Compiler complains that wchar[] != immutable(char)[]
    wchar[] wstr = "This is a wchar[]";
	
    // Compiler accepts this
    wchar[] wstr = "This is a wchar[]"w.dup;

    // Compiler accepts this
    wchar[] wstr;
    wstr ~= "This is a wchar[]";

If the compiler knows the type in the last example with concatenation, 
shouldn't it be able to figure that out in the first example.

I am using windows and DMD HEAD.

Thanks,
ollie
Feb 04 2013
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/04/2013 10:13 AM, ollie wrote:
 I am using wchar[] and find the usage clunky. Am I doing something wrong?

 Example:
      // Compiler complains that wchar[] != immutable(char)[]
      wchar[] wstr = "This is a wchar[]";
There is nothing but a wchar slice that is going to provide access to the chars on the right-hand side. Unfortunately that is not possible because neither the right-hand side has wchars nor they are mutable.
      // Compiler accepts this
      wchar[] wstr = "This is a wchar[]"w.dup;
That's fine: You explicitly make a mutable wchar array.
      // Compiler accepts this
      wchar[] wstr;
      wstr ~= "This is a wchar[]";
That's fine because the binary ~ operator always makes copies of elements.
 If the compiler knows the type in the last example with concatenation,
 shouldn't it be able to figure that out in the first example.
The missing bit is that a copy of the char literal itself is not made automatically. Ali
Feb 04 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/04/2013 10:22 AM, Ali Çehreli wrote:
 On 02/04/2013 10:13 AM, ollie wrote:
  > I am using wchar[] and find the usage clunky. Am I doing something
 wrong?
  >
  > Example:
  > // Compiler complains that wchar[] != immutable(char)[]
  > wchar[] wstr = "This is a wchar[]";

 There is nothing but a wchar slice that is going to provide access to
 the chars on the right-hand side. Unfortunately that is not possible
 because neither the right-hand side has wchars nor they are mutable.
As Steven's post shows, it would work if the left-hand side was immutable: immutable(wchar)[] wstr = "This is a wchar[]"; That line involves some help from the compiler: Because the type of the literal on the right-hand side is not specified, the compiler makes one that matches the type of the left-hand side. In other words, one should not do what I did and assume that literals "like this" are always char arrays. They are char arrays only when there is c at the end "like this"c. Otherwise, although they default to char, the actual type is decided by the compiler. Ali
Feb 04 2013
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Feb 2013 13:13:22 -0500, ollie <ollie home.net> wrote:

 I am using wchar[] and find the usage clunky. Am I doing something wrong?

 Example:
     // Compiler complains that wchar[] != immutable(char)[]
     wchar[] wstr = "This is a wchar[]";
It's not so much the wchar vs. char, but the mutable vs. immutable. It could be argued that the message should say "wchar[] != wstring" instead. This works: immutable(wchar)[] wstr = "This is a wchar[]"; or wstring wstr = "This is a wchar[]";
 	
     // Compiler accepts this
     wchar[] wstr = "This is a wchar[]"w.dup;
Right, because you are duplicating the string onto the heap, and making it mutable.
     // Compiler accepts this
     wchar[] wstr;
     wstr ~= "This is a wchar[]";

 If the compiler knows the type in the last example with concatenation,
 shouldn't it be able to figure that out in the first example.
No, because the first example does not involve heap allocation, just straight assignment. Appending involves concatenation, and making a copy of the original, so it is safe to do so. -Steve
Feb 04 2013
parent reply ollie <ollie home.net> writes:
On Mon, 04 Feb 2013 13:28:43 -0500, Steven Schveighoffer wrote:

 On Mon, 04 Feb 2013 13:13:22 -0500, ollie <ollie home.net> wrote:
 
     wchar[] wstr = "This is a wchar[]";
It's not so much the wchar vs. char, but the mutable vs. immutable. It could be argued that the message should say "wchar[] != wstring" instead.
I am aware of the immutable/mutable issue. My intention was a mutable string.
 Right, because you are duplicating the string onto the heap, and making
 it mutable.
I thought druntime always created dynamic arrays on the heap and returned a slice.
     // Compiler accepts this wchar[] wstr;
     wstr ~= "This is a wchar[]";
No, because the first example does not involve heap allocation, just straight assignment. Appending involves concatenation, and making a copy of the original, so it is safe to do so.
What is the storage (heap/stack) of "straight assignment" if this were a local variable. Or do you mean that "This is a wchar[]" was already created on the heap as an immutable(wchar)[] then assigned to wstr. Thanks for your replies Steven and Ali, ollie
Feb 04 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 04, 2013 19:45:02 ollie wrote:
 Right, because you are duplicating the string onto the heap, and making
 it mutable.
I thought druntime always created dynamic arrays on the heap and returned a slice.
It does, but duping or iduping an array or string literal would allocate _again_. Also, in at least some cases (e.g. Linux) string literals end up in ROM such that they're shared (both across threads and across uses - e.g. multiple uses of the string literal "hello world" will potentially end up being exactly the same string in memory). As such, they're actually allocated as part of the program itself rather than when they're used (unlike with normal array literals). So, doing auto str = "hello world"; won't necessarily allocate anything. But I believe that that's implementation- dependent (e.g. I'm don't think that that happens on Windows). - Jonathan M Davis
Feb 04 2013
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Feb 2013 14:45:02 -0500, ollie <ollie home.net> wrote:

 What is the storage (heap/stack) of "straight assignment" if this were a
 local variable.  Or do you mean that "This is a wchar[]" was already
 created on the heap as an immutable(wchar)[] then assigned to wstr.
The string is actually stored in code, not on the heap. When you assign, you get a pointer right into code (ROM). On some OSes, you can possibly modify this value, on some you will get a memory error. In D1, where there was no immutable, string literals *were* char[]. Then you could have funky stuff like this: auto str = "hello"; str[0] = 'j'; auto str2 = "hello"; writefln(str2); // writes "jello" Of course, this only worked on one of the OSes (I think it was windows). On the others you would get an error. Array literals are different, they are allocated on the heap when they are used. so ['h', 'e', 'l', 'l', 'o'] is very different than "hello". There has in the past been a push to make ALL array literals immutable, but it has never gone anywhere. -Steve
Feb 04 2013
parent ollie <ollie home.net> writes:
On Mon, 04 Feb 2013 15:09:06 -0500, Steven Schveighoffer wrote:

 On Mon, 04 Feb 2013 14:45:02 -0500, ollie <ollie home.net> wrote:
 
 What is the storage (heap/stack) of "straight assignment" if this were
 a local variable.  Or do you mean that "This is a wchar[]" was already
 created on the heap as an immutable(wchar)[] then assigned to wstr.
The string is actually stored in code, not on the heap. When you assign, you get a pointer right into code (ROM).
I seem to remember that now (had a brain fart). Thank you Jonathan and Steven for your help. ollie
Feb 04 2013