On Saturday, 30 June 2012 at 00:27:46 UTC, Jonathan M Davis wrote:
On Saturday, June 30, 2012 02:12:22 mta`chrono wrote:
does anyone know why string not implicit convertable to const(char*) ?

-------
import core.sys.posix.unistd;

void main()
{
        // ok
        unlink("foo.txt");

        // failed
        string file = "bar.txt";
        unlink(file);
}

test.d(10): Error: function core.sys.posix.unistd.unlink (const(char*))
is not callable using argument types (string)
test.d(10): Error: cannot implicitly convert expression (file) of type
string to const(char*)

Because it's _not_ const char*. It's an array. And passing a string directly to a C function (which is almost the only reason that you'd want a string to convert to a const char*) is generally _wrong_. Strings in D are _not_ zero- terminated. String _literals_ are (they have a '\0' one character passed their end), so as it just so happens, if string implicitly converted to const char*, your code would work, but if your string had been created from anything other than a string literal, it would _not_ be zero terminated. Even concatenating two string literals results in a string which isn't zero-terminated. So, implictly converting strinvg to const char* would just cause bugs (in fact, it _used_ to work, and it was fixed so that it doesn't precisely because it's
behavior which just causes bugs).

What you need to do is use std.string.toStringz. It converts a string to a zero-terminated string. It appends '\0' to the end of the string if it has to (which could result in the string having to be reallocated to make room for it), but if it can determine that it's unnecessary (which it can do at least some of the time with string literals), it'll just return the string's ptr property without doing any allocating. But since you _need_ that '\0', that's the best that you can do. Simply passing the string's ptr property to a C
function would be wrong, since it's not zero-terminated.

Your function call should look like

unlink(toStringz(file));

Of course, you could just do std.file.remove(file), which ultimately does the same thing and does so on all platforms rather than just POSIX, but that's a
separate issue from converting a string to a const char*.

- Jonathan M Davis

Thanks for the thorough explanation, but it begs the question why not make strings be array of chars that have \0 at the end of it? Since, lots of D programmers were/are probably C/C++ programmers, why should D be different here? Wouldn't it facilitate more C/C++ programmers to come to D?

Just curious.


Reply via email to