On 02/27/2018 06:32 PM, Atila Neves wrote:
On Tuesday, 27 February 2018 at 12:39:04 UTC, Jonathan M Davis wrote:
[...]
In almost all cases, &a[0] is equivalent to a.ptr except that it does bounds checking, so it's actually @safe and thus doesn't need to be manually verified by the programmer, unlike your pointer function suggestion.

There's a common case where it's not equivalent - when the pointer is null. Imagine I have a C function I want to call:

extern(C) void fun(int* things);

Imagine also that it's ok to call with null. Well, now I can't use a slice to call this and have it be 1) @safe and 2) not throw RangeError. I ran into this the other way.

As Jonathan says, you have to manually verify that it's safe, because it generally isn't. `arr.ptr` can be invalid but not null, even in @safe code.

Consider:

----
void fun(int* things) @safe
{
    int x = things is null ? 0 : *things;
    import std.stdio;
    writeln(x);
}

void main()
{
    int[] arr;
    fun(arr.ptr); /* Ok, prints "0". */

    arr = [1, 2, 3];
    fun(arr.ptr); /* Ok, prints "1".*/

    arr = arr[$ .. $]; /* This is @safe. */
    fun(arr.ptr); /* Not ok, prints garbage. */
}
----

The first two calls are actually safe and can be @trusted. The third call is invalid and must not be possible in @safe code.

Maybe it would be possible require `arr.ptr` to be valid or null in @safe code. This would outlaw `arr[$ .. $]` and bounds checking would have to catch it. I don't know if that would be any practical than banning `arr.ptr`.

Reply via email to