7
votes

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.

4
That page is way out of date. Check ftp.digitalmars.com for the real latest version of DMD. - dsimcha
The word invariant has been replaced with immutable and will not exist in the stable release of D2.x - he_the_great

4 Answers

10
votes

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.

9
votes

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 :)

4
votes

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

auto s = "some text";

let the compiler worry about the type.

4
votes

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.