On Thursday, 18 February 2016 at 18:58:56 UTC, H. S. Teoh wrote:
On Thu, Feb 18, 2016 at 06:50:34PM +0000, Jonathan M Davis via Digitalmars-d wrote:
On Thursday, 18 February 2016 at 18:41:25 UTC, Steven Schveighoffer wrote:
[...]
>foo(void[] arr)
>{
>   void[] arr2 = [1234, 5678, 91011];
>   arr[] = arr2[0 .. arr.length];
>}

Well, I'm not sure that that's actually not @safe.

How can it possibly be @safe??? Consider:

        void main() @safe {
                Object[] objs = [ new Object() ];
                foo(objs);
        }

Now the pointer to the Object instance has been corrupted.

Does it matter what state the void[] is in until you actually attempt to cast it to something else? If you have

Object[] oArr = [ new Object ];
void[] vArr = oArr;
vArr = vArr[0 .. $ - 1];

it's not like that's going to cause any problems - not by itself. As soon as you convert it back to Object[] or to int[] or whatever, _then_ you're screwed. But converting from void[] to anything is inherently @system regardless of what you did to the array or where it came from. Now, given that reducing the length like that is setting you up for a bad conversion, I can certainly see an argument for reducing the length of a void[] being @system, but in and of itself, it isn't going to corrupt memory. It just sets the stage for it. As long as it stays void[], everything is fine.

Now given that you can't possibly do anything useful with reducing the length of void[] and that it does make it so that future, @system operations would corrupt memory, I can certainly see making it @system, but I dispute that it's really doing anything unsafe on its own.

It's trying to interpret the void[] that's the problem. Certainly, you can convert T[] to void[] and pass it around all day without risking any memory corruption, so that should definitely be @safe, and I don't see how reducing the length of a void[] could actually cause memory corruption on its own. It's when you cast the void[] to something else that you risk things going south, and that's what needs to be @system. So, I'm not sure that there's actually any reason for your example code to not be @safe.
[...]

I think you missed the point of his example. :-) The point is that it's perfectly legal to (1) cast an array of int to void[], and (2) it's also perfectly legal to cast an array of anything to void[], and (3) under current rules, it's perfectly legal to copy one void[] to another
void[].

Arguably, (3) should not be allowed in @safe code. Which again brings us back to the point, that if any function takes void[] as an argument, is there *anything* it can do with the void[] other than reading it, that *won't* break @safe?

If there's *nothing* it can legally do with a void[] (other than reading it) without violating @safe, then shouldn't it be a requirement that all functions marked @safe must take const(void)[] rather than void[]?

It could pass it to something else without actually doing anything to it, in which case, I don't see why it couldn't be @safe. It's interpreting a void[] that's the problem. _That_ needs to be @system. Merely converting to void[] or passing it around is harmless. And as long as converting void[] to anything else is considered @system like it should be, I don't see why it would be necessary to care about whether a function accepts void[] or not when considering @safety. Useless as it may be

    void[] identity(void[] arr) @safe
    {
        return arr;
    }

is perfectly @safe. If the compiler does its job, and the function does cast the void[], then the function will be considered @system unless it's marked @trusted, and all is well without caring one whit about how the function was passed void[].

The problem with std.socket is not that it accepts void[] and considers that @safe; it's that it passes that void[] to something else, treating that as @safe, when it's not. And since it's a C function that's being called, and it accesses the ptr member of the void[], it's already @system, forcing @trusted to be used to make the compiler happy. So, the problem is that @trusted was used when it shouldn't have been, not that the type system allowed void[] to be passed in without marking it as @system. And since the function was marked @trusted, it's not like having the compiler treat a function that accepted void[] as @system would have helped anyway.

- Jonathan M Davis

Reply via email to