Shouldn't casting an object to void* be considered @safe?

Dennis dkorpel at gmail.com
Sat Dec 14 20:53:49 UTC 2019


On Saturday, 14 December 2019 at 19:16:08 UTC, Joseph Rushton 
Wakeling wrote:
> Indeed.  Has anything I said suggested otherwise?

My bad, I thought you were implying that it shouldn't be @safe 
because it isn't useful.

> That's relevant to this discussion, because when asking "Should 
> the cast to `void*` be @safe?" we are really asking, "Is it 
> possible for the compiler to decide this without needing the 
> developer to verify?"

The compiler should only be concerned with verifying what it 
knows. E.g. if a `bool*` reaches `@safe` code, it must be null or 
point to a mutable 0 or 1 value. I don't think adding any 
additional rules is helpful. You might also say "casting ubyte[] 
to char[] should be unsafe because the compiler doesn't know 
whether the developer's string functions exhibit undefined 
behavior on invalid unicode", but if the developer relies on 
correct unicode like that, his functions are incorrectly marked 
@trusted. If you want that guarantee, you should not use char[] 
but make your own struct type that ensures that.

A void* is an opaque pointer type. If I start writing a function 
like:
```
void setZero(void* ptr) @trusted {

}
```
I simply can't assume anything about ptr other than that it is a 
valid `void*`.

It does raise the question what can be assumed about a `void*`.
You could say that a void* must point to at least 1 byte of 
mutable memory, such that this function is correctly @trusted:

```
void setZero(void* ptr) @trusted {
     if (ptr) {
         *(cast(ubyte) ptr) = 0;
     }
}
```

However, I'd argue a void* is even more opaque than that, since 
it's not uncommon to use them as generic 'handles' in C 
libraries, such as HMODULE in the Windows API:
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress

> we are creating opportunities for unsafe memory access that 
> didn't exist previously.

I doubt that. If you have a code example, I'm very interested. I 
bet that any @trusted code that can be broken by allowing 
cast(void*) in @safe code can also be broken without that.

> No, that won't do.  What if you cast from a `ulong` to a 
> `void*`?

That is `@safe`, unless there is a way to corrupt memory in 
`@safe` code by doing that.




More information about the Digitalmars-d mailing list