On 8/15/21 2:10 AM, rempas wrote:
So when I'm doing something like the following: `string name = "John";`
Then what's the actual type of the literal `"John"`?
In the chapter [Calling C functions](https://dlang.org/spec/interfaceToC.html#calling_c_functions) in the "Interfacing with C" page, the following is said:
Strings are not 0 terminated in D. See "Data Type Compatibility" for more information about this. However, string literals in D are 0 terminated.

Which is really interesting and makes me suppose that `"John"` is a string literal right? However, when I'm writing something like the following: `char *name = "John";`,
then D will complain with the following message:
Error: cannot implicitly convert expression `"John"` of type `string` to `char*`

Which is interesting because this works in C. If I use `const char*` instead, it will work. I suppose that this has to do with the fact that `string` is an alias for `immutable(char[])` but still this has to mean that the actual type of a LITERAL string is of type `string` (aka `immutable(char[])`).

Another thing I can do is cast the literal to a `char*` but I'm wondering what's going on under the hood in this case. Is casting executed at compile time or at runtime? So am I going to have an extra runtime cost having to first construct a `string` and then ALSO cast it to a string literal?

I hope all that makes sense and the someone can answer, lol

Lots of great responses in this thread!

I wanted to stress that a string literal is sort of magic. It has extra type information inside the compiler that is not available in the normal type system. Namely that "this is a literal, and so can morph into other things".

To give you some examples:

```d
string s = "John";
immutable(char)* cs = s; // nope
immutable(char)* cs2 = "John"; // OK!
wstring ws = s; // nope
wstring ws2 = "John"; // OK!
```

What is going on? Because the compiler knows this is a string *literal*, it can modify the type (and possibly the data itself) at will to match what you are assigning it to. In the case of zero-terminated C strings, it allows usage as a pointer instead of a D array. In the case of different width strings (wstring uses 16-bit code-units), it can actually transform the underlying data to what you wanted.

Note that even when you do lose that "literal" magic by assigning to a variable, you can still rely on D always putting a terminating zero in the data segment for a string literal. So it's valid to just do:

```d
string s = "John";
printf(s.ptr);
````

As long as you *know* the string came from a literal.

-Steve

Reply via email to