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