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