Jump to page: 1 2
Thread overview
Why is &array[0] @safer than array.ptr?
Jan 24, 2017
Atila Neves
Jan 24, 2017
Stefan Koch
Jan 24, 2017
TheFlyingFiddle
Jan 24, 2017
Atila Neves
Jan 25, 2017
David Nadlinger
Jan 24, 2017
Jonathan M Davis
Jan 24, 2017
Rene Zwanenburg
Jan 24, 2017
Jonathan M Davis
Jan 24, 2017
Dukc
Jan 25, 2017
Kagamin
Jan 25, 2017
Jonathan M Davis
Jan 25, 2017
David Nadlinger
Jan 26, 2017
Jerry
Jan 25, 2017
David Nadlinger
Jan 25, 2017
Adam D. Ruppe
Jan 25, 2017
David Nadlinger
Jan 25, 2017
Adam D. Ruppe
Jan 25, 2017
Jonathan M Davis
Jan 25, 2017
David Nadlinger
Jan 26, 2017
Dukc
January 24, 2017
void main() {
    foo;
}

void foo() @safe {
    int[] array;
    auto ptr = array.ptr;
}


foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead


&array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe.

Atila
January 24, 2017
On Tuesday, 24 January 2017 at 11:28:17 UTC, Atila Neves wrote:
> void main() {
>     foo;
> }
>
> void foo() @safe {
>     int[] array;
>     auto ptr = array.ptr;
> }
>
>
> foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead
>
>
> &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe.
>
> Atila

the type is still a type with bounds and not an unbounded pointer.
January 24, 2017
On Tuesday, 24 January 2017 at 11:28:17 UTC, Atila Neves wrote:
> void main() {
>     foo;
> }
>
> void foo() @safe {
>     int[] array;
>     auto ptr = array.ptr;
> }
>
>
> foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead
>
>
> &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe.
>
> Atila

Just a speculative guess.

unittest @safe
{
   int[] array;

   auto ptr  = array.ptr; //could be null
   auto ptr2 = &array[0]; //Does a bounds check?
   auto ptr3 = &array[5]; //Should do a bounds check.
}
January 24, 2017
On Tuesday, January 24, 2017 11:28:17 Atila Neves via Digitalmars-d-learn wrote:
> void main() {
>      foo;
> }
>
> void foo() @safe {
>      int[] array;
>      auto ptr = array.ptr;
> }
>
>
> foo.d(7): Deprecation: array.ptr cannot be used in @safe code,
> use &array[0] instead
>
>
> &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe.

Likely because it does bounds checking, so you at least know that it's not null. But I don't see why that would really improve much considering that the odds are that you're really going to be accessing far more than just the first element with the pointer. It seems _slightly_ better from a safety perspective but only slightly. So, I don't know what the point is in suggesting it as an alternative.

- Jonathan M Davis

January 24, 2017
On Tuesday, 24 January 2017 at 11:32:47 UTC, TheFlyingFiddle wrote:
> On Tuesday, 24 January 2017 at 11:28:17 UTC, Atila Neves wrote:
>> void main() {
>>     foo;
>> }
>>
>> void foo() @safe {
>>     int[] array;
>>     auto ptr = array.ptr;
>> }
>>
>>
>> foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead
>>
>>
>> &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe.
>>
>> Atila
>
> Just a speculative guess.
>
> unittest @safe
> {
>    int[] array;
>
>    auto ptr  = array.ptr; //could be null
>    auto ptr2 = &array[0]; //Does a bounds check?
>    auto ptr3 = &array[5]; //Should do a bounds check.
> }

&array[5] makes sense to bounds check, and I guess then the issue is I could instead do `array.ptr + 5` which would be bad. But it's still annoying to have to do &array[0] just to pass it to a C function, since `my_c_func(array.ptr)` isn't going to screw up anything.

BTW, in that example above array.ptr is null even though array is null. It doesn't crash.

Atila



January 24, 2017
On Tuesday, 24 January 2017 at 11:38:16 UTC, Jonathan M Davis wrote:
> Likely because it does bounds checking, so you at least know that it's not null. But I don't see why that would really improve much considering that the odds are that you're really going to be accessing far more than just the first element with the pointer. It seems _slightly_ better from a safety perspective but only slightly. So, I don't know what the point is in suggesting it as an alternative.
>
> - Jonathan M Davis

Pointer arithmetic is forbidden in @safe code so that's not a problem. The reason this was introduced was indeed bounds checking. For example:

@safe:

int parse(ref char[] input)
{
  // Pop all numeric characters from the front of the input slice and convert to int
}

void main()
{
  auto input = "123".dup;
  parse(input);
  // Since all numeric chars have been popped, input is now effectively input[$ .. $].
  // This means input.ptr is pointing past the end of the array.
  writeln(input.ptr); // Out of bounds access
}
January 24, 2017
On Tuesday, January 24, 2017 11:50:16 Rene Zwanenburg via Digitalmars-d- learn wrote:
> On Tuesday, 24 January 2017 at 11:38:16 UTC, Jonathan M Davis
>
> wrote:
> > Likely because it does bounds checking, so you at least know that it's not null. But I don't see why that would really improve much considering that the odds are that you're really going to be accessing far more than just the first element with the pointer. It seems _slightly_ better from a safety perspective but only slightly. So, I don't know what the point is in suggesting it as an alternative.
> >
> > - Jonathan M Davis
>
> Pointer arithmetic is forbidden in @safe code so that's not a problem. The reason this was introduced was indeed bounds checking. For example:
>
> @safe:
>
> int parse(ref char[] input)
> {
>    // Pop all numeric characters from the front of the input slice
> and convert to int
> }
>
> void main()
> {
>    auto input = "123".dup;
>    parse(input);
>    // Since all numeric chars have been popped, input is now
> effectively input[$ .. $].
>    // This means input.ptr is pointing past the end of the array.
>    writeln(input.ptr); // Out of bounds access
> }

Sure, there can be problems with .ptr. It's not necessarily a problem that it's not @safe. But doing &arr[0] instead of arr.ptr is almost pointless. All it does is verify that the array isn't null or empty. If you're doing arr.ptr, you're almost certainly passing it to C code, and that code will almost certainly read well past the arr[0].

So, while it makes sense to say that .ptr can't be used in @safe code, it really doesn't make sense to suggest &arr[0] as an alternative.

- Jonathan M Davis

January 24, 2017
On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis wrote:
> So, while it makes sense to say that .ptr can't be used in @safe code, it really doesn't make sense to suggest &arr[0] as an alternative.

That may well be. But I believe everything that can provably be @safe are made so even when apparently pointeless, because someone may find creative uses for those things. Ones the creators did not think of. And even if there are none now, that may change in the future with the language or libraries.


January 25, 2017
On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis wrote:
> So, while it makes sense to say that .ptr can't be used in @safe code, it really doesn't make sense to suggest &arr[0] as an alternative.

When you ensure pointers point to existing data, you can dereference them in safe code, otherwise you can't.
January 25, 2017
On Wednesday, January 25, 2017 10:52:51 Kagamin via Digitalmars-d-learn wrote:
> On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis
>
> wrote:
> > So, while it makes sense to say that .ptr can't be used in @safe code, it really doesn't make sense to suggest &arr[0] as an alternative.
>
> When you ensure pointers point to existing data, you can dereference them in safe code, otherwise you can't.

Fine, but in the vast majority of cases, you're calling .ptr, because you're going to be passing the pointer to C code, in which case, doing &arr[0] buys you very little, since the C code is inevitably going to be reading more than that one element, and &arr[0] hasn't verified anything beyond the first element. So, telling the programmer to use &arr[0] instead of arr.ptr is just plain bizarre. Doing &arr[0] makes sense when you're just going to be messing with that one element in D code, but that's pretty much it. Otherwise, you might as well just use arr.ptr, because it's up to the programmer to verify the @safety of what's going on at that point anyway.

- Jonathan M Davis

« First   ‹ Prev
1 2