On Sunday, 15 August 2021 at 06:10:53 UTC, rempas wrote:
So when I'm doing something like the following: `string name = "John";`
Then what's the actual type of the literal `"John"`?

```d
unittest {
    pragma(msg, typeof("John"));  // string
    pragma(msg, is(typeof("John") == immutable(char)[]));  // true
}
```

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.

```d
void zerort(string s) {
    assert(s.ptr[s.length] == '\0');
}

unittest {
    zerort("John"); // assertion success
    string s = "Jo";
    s ~= "hn";
    zerort(s); // assertion failure
}
```

If a function takes a string as a runtime parameter, it might not be NUL terminated. This might be more obvious with substrings:

```d
unittest {
    string j = "John";
    string s = j[0..2];
    assert(s == "Jo");
    assert(s.ptr == j.ptr);
    assert(s.ptr[s.length] == 'h'); // it's h-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.

Well, kinda:

```c
void mutate(char *s) {
    s[0] = 'X';
}

int main() {
    char *s = "John";
    mutate(s); // segmentation fault
}
```

`char*` is just the wrong type, it suggests mutability where mutability ain't.

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.

The same thing as in C:

```d
void mutate(char *s) {
    s[0] = 'X';
}

void main() {
    char* s = cast(char*) "John";
    mutate(s); // program killed by signal 11
}
```

Is casting executed at compile time or at runtime?

Compile-time. std.conv.to is what you'd use at runtime. Here though, what you want is `dup` to get a `char[]`, which you can then take the pointer of if you want:

```d
unittest {
    char* s = "John".dup.ptr;
    s[0] = 'X'; // no segfaults
    assert(s[0..4] == "Xohn"); // ok
}
```

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


Reply via email to