Shouldn't casting an object to void* be considered @safe?
Dennis
dkorpel at gmail.com
Sun Dec 15 11:21:39 UTC 2019
On Saturday, 14 December 2019 at 23:48:38 UTC, Joseph Rushton
Wakeling wrote:
> ulong u = 8;
> auto v = cast(void*) u;
> ... is totally unsafe, and the compiler rightly rejects it if
> you try to do that in a code block marked @safe.
It is not sufficient for causing memory corruption in @safe code.
> But you shouldn't need the compiler to tell you to know that
> this is a really messed up thing to do.
If "messed up" means that it can cause memory corruption in @safe
code, then you haven't demonstrated that yet.
It "messed up" means that it is a bad practice, then we are back
to "@safe is about eliminating memory corruption possibilities,
not bug free / good practice / useful".
> How do you know that memory address 8 is in any way valid?
You don't. That's the point of void*, you cannot safely cast it
to any pointer. You can safely cast it to an integer and use
that, or pass it to @safe functions that use it safely.
```
import std.stdio: writeln;
void main() {
import core.sys.windows.winbase: CreateSemaphoreW,
CloseHandle;
void* fromMe = cast(void*) 516; // currently not @safe, but
should be
void* fromC = CreateSemaphoreW(null, 8, 8, null);
writeln("fromMe: ", cast(size_t) fromMe); // 516
writeln("fromC: ", cast(size_t) fromC); // could be 516 as
well
CloseHandle(fromMe); // likely won't succeed, but won't
corrupt memory
CloseHandle(fromC);
badTrusted(fromMe); // NO!
badTrusted(fromC); // NO! But still possible when disallowing
@safe cast(void*)
}
void badTrusted(void* ptr) @trusted {
writeln(*(cast(ubyte*) ptr)); // this is simply bad
}
```
More information about the Digitalmars-d
mailing list