tags:

views:

495

answers:

4

This may sound really stupid. but I've got a strange problem with the D programming language. When I try to create a new array like this:

import std.stdio;

void main()
{
    char[] variable = "value";
    writefln(variable);
}

The DMD compiler always gives me this error:

test.d(5): Error: cannot implicitly convert expression ("value") of type invariant(char[5u]) to char[]

Any idea why? I'm using the 2.014 alpha (available here) for Ubuntu.

+6  A: 

I was searching around the arrays section of the guide, this may help:

A string is an array of characters. String literals are just an easy way to write character arrays. String literals are immutable (read only).

char[] str1 = "abc";                // error, "abc" is not mutable
char[] str2 = "abc".dup;            // ok, make mutable copy
invariant(char)[] str3 = "abc";     // ok
invariant(char)[] str4 = str1;      // error, str4 is not mutable
invariant(char)[] str5 = str1.idup; // ok, make invariant copy

From here.

ryeguy
Thanks a lot, should have taken a look myself. I don't understand the whole thing about the mutable and immutable not really though. Why can't I simply assign an immutable char sequence to a char array?
because your variable is a _mutable_ char array pointer, that is, a pointer to the mutable char array, and you're trying to make it point to an _inmutable_ char array.
Javier
http://bartoszmilewski.wordpress.com/2009/02/05/immutable-things-where-do-they-all-come-from/ might be worth a read
Pete Kirkham
Thanks a lot to you both!
+8  A: 

Basically, what it comes down to is that string literals are stored in a read-only part of memory. char[] is "a mutable array of mutable characters", which would, if written to, generate a run-time crash.

So the compiler is really trying to protect you here.

invariant(char)[] means "a mutable array of invariant characters", which is exactly what it is.

PS: When you don't need it to be a char[], you might want to use auto, as in, auto variable = "value". Frees you from thinking about its type :)

FeepingCreature
Thank you for the very clear and simple explanation, FeppingCreature.
+1  A: 

use auto and don't worry what the type is:

auto s = "some text";

let the compiler worry about the type.

hasen j
+1  A: 

There are two main versions of the D language. They are, in general, mutually incompatible with each other, although code can be written to compile in both.

D1 is what the code you supplied seems to be written in. It doesn't have a concept of immutable arrays, hence this works.

D2 is what you are trying to compile it as, hence the 2 beginning the compiler version number. One of the main D2-specific features is this concept of const and immutable/invariant data references.

char[] text;              // mutable data
const(char)[] ctext;      // data may be mutable or immutable - but either way,
                          // it will not be changed through this reference
invariant(char)[] itext;  // immutable data

String literals in D2 are classed as immutable data, and therefore cannot be assigned to a char[], but only a const(char)[] or invariant(char)[] (or wchar or dchar equivalents).

string is an alias of invariant(char)[], which you may want to use either for convenience or for D1 compatibility.

Stewart
The word invariant has been replaced with immutable and will not exist in the stable release of D2.x
he_the_great
I was going by the spec - except that digitalmars.com/d/2.0/const3.html seems to have now finally been fixed. According to most other pages, the word is still invariant. (I also think you'll find that invariant will always be the word for class invariants, but that's an aside.)
Stewart