Safe cast of arrays

Chris Wright via Digitalmars-d digitalmars-d at puremagic.com
Wed Feb 10 12:14:29 PST 2016


On Wed, 10 Feb 2016 08:49:21 +0000, w0rp wrote:

> I think this should be addressed, as if you can't cast between pointer
> types, you shouldn't be allowed to cast between slice types either.
> Because slices are just a pointer plus a length. Another way to
> demonstrate the problem is like this.
> 
> @safe int* badCast(long[] slice) {
>      return (cast(int[]) slice).ptr;
> }
> 
> 
> @system void main(string[] argv) {
>      auto larger = new long[5];
>      auto smaller = badCast(larger);
> }

@safe protects you from segmentation faults and reading and writing 
outside an allocated segment of memory. With array casts, @safety is 
assured:

int[] a = [1, 2, 3, 4];
long[] b = cast(long[])a;
writeln(b.length);  // prints "2"

Versus:
int[] a = [1, 2, 3, 4, 5];
long[] b = cast(long[])a;

This throws an "object.Error: array cast misalignment" specifically 
because there's no correct, safe way to execute the cast. You'd be left 
with a dangling half of a long.

But if you're using pointers, the runtime can't do this kind of 
validation, so it's not @safe to cast int* to long*. It is, however, safe 
to cast long* to int*, because writing four bytes to a long* won't 
overflow the memory allocated to it.

So this isn't a problem with @safe.

Show a way to read or write outside allocated memory with this, or to 
cause a segmentation fault, and that will require a change in @safe. 
You're looking for something else, data safety rather than memory safety. 
You want to disallow unions and anything that lets you emulate them.


More information about the Digitalmars-d mailing list