why is string not implicit convertable to const(char*) ?
Jonathan M Davis
jmdavisProg at gmx.com
Fri Jun 29 17:27:30 PDT 2012
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
More information about the Digitalmars-d-learn
mailing list