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.