On Saturday, 7 February 2015 at 23:50:55 UTC, Andrei Alexandrescu
wrote:
I was looking into ways to make core.stdc safer. That should be
relatively easy to do by defining a few wrappers. For example:
int setvbuf(FILE* stream, char* buf, int mode, size_t size);
is unsafe because there's no relationship between buf and size.
But this is fine:
@trusted int setvbuf(T)(FILE* stream, T[] buf, int mode)
if (is(T == char) || is(T == byte) || is(T == ubyte))
{
return setvbuf(stream, cast(char*) buf.ptr, mode,
buf.length);
}
Another example is:
int stat(in char*, stat_t*);
which may start reading through random memory if the string is
not zero-terminated. Again, the solution is here to ensure the
string does have a terminating zero:
@trusted int stat(in char[] name, stat_t* p)
{
if (isZeroTerminated(name)) return stat(name.ptr, p);
auto t = cast(char*) malloc(name.length + 1);
scope(exit) free(t);
memcpy(t, name.ptr, name.length);
t[name.length] = 0;
return stat(t, p);
}
Such wrappers would allow safe code to use more C stdlib
primitives. The question is whether these wrappers are worth
adding to core.stdc.stdio.
Thanks,
Andrei
One of the reasons why I use C functions is that I expect same
behaviour from D code what I would expect from C. I don't think
it is a good idea to make wrapper on top of them. Maybe you could
say, "Hey, look, it just makes safer, that's all", but, hmm there
are so many functions, and this wrapping process can go in many
directions.