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