why is string not implicit convertable to const(char*) ?
dcoder
dcoder at nowhere.com
Thu Jul 5 12:32:11 PDT 2012
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.
More information about the Digitalmars-d-learn
mailing list