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