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));