Is there a way to slice non-array type in @safe?
Paul Backus
snarwin at gmail.com
Fri Jul 12 00:59:40 UTC 2019
On Thursday, 11 July 2019 at 19:44:51 UTC, Stefanos Baziotis
wrote:
> On Thursday, 11 July 2019 at 19:37:38 UTC, Nathan S. wrote:
>>
>> If you know that what you're doing cannot result in memory
>> corruption but the compiler cannot automatically infer @safe,
>> it is appropriate to use @trusted. (For this case make sure
>> you're not returning the byte slices, since if the arguments
>> were allocated on the stack you could end up with a pointer to
>> an invalid stack frame. If it's the caller's responsibility to
>> ensure the slice doesn't outlive the struct then it is the
>> caller that should be @trusted or not.)
>
> Yes, @trusted is an option. I mean it's a good solution, but
> from the standpoint of the language user, it seems unfortunate
> that for the case static types
> @trusted has to be used while the array one can be @safe:
>
> int memcmp(T)(const T[] s1, const T[] s2) @safe
> {
> const byte[] s1b = (cast(const(byte[]))s1)[0 .. s1.length *
> T.sizeof];
> const byte[] s2b = (cast(const(byte[]))s2)[0 .. s2.length *
> T.sizeof];
> }
You can use a union:
int foo(T)(ref T s1, ref T s2) {
import std.stdio;
union U {
T val;
byte[T.sizeof] bytes;
}
const U s1u = { val: s1 };
const U s2u = { val: s2 };
writeln("s1 bytes: ", s1u.bytes);
writeln("s2 bytes: ", s2u.bytes);
return 0;
}
@safe void main() {
double a = 12.345, b = 67.890;
foo(a, b);
}
However, accessing the `bytes` member will still be considered
@system if T is or contains a pointer. To fix this, you can use a
@trusted nested function to do the union access; e.g.,
@trusted ref const(ubyte[T.sizeof]) getBytes(ref U u) {
return u.bytes; }
// ...
writeln("s1 bytes: ", getBytes(s1u));
More information about the Digitalmars-d-learn
mailing list