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.

Reply via email to