December 15, 2019
On Sunday, 15 December 2019 at 09:15:39 UTC, Joseph Rushton Wakeling wrote:
> Which brings us back to the start of the discussion: @safe checks are not just about the strictest definition of memory safety, but also about actions that open up a path to unsafe behaviour unless they are carefully validated.

You can demonstrate that by giving a piece of @trusted code that is correct when @safe casting to cast(void*) is disallowed and incorrect when it is allowed. My guess is that you haven't done that, because cast(void*) doesn't actually open up any paths to unsafe behavior that weren't previously there. I love to be proven wrong about this though.

> You may not accept the principle but that is the reality of the spec.

What part of the spec are you referring to? I'm mostly concerned with:

> Memory safety does not imply that code is portable, uses only sound programming practices, is free of byte order dependencies, or other bugs. It is focussed only on eliminating memory corruption possibilities.

https://dlang.org/spec/memory-safe-d.html#limitations
December 16, 2019
On Saturday, 14 December 2019 at 17:25:25 UTC, Joseph Rushton Wakeling wrote:
> Surely where code has a cast to `void*` and then later back to some other pointer type

The question was only about the first part, casting to void*, not casting back.
December 16, 2019
On Monday, 16 December 2019 at 01:01:26 UTC, Andrej Mitrovic wrote:
> On Saturday, 14 December 2019 at 17:25:25 UTC, Joseph Rushton Wakeling wrote:
>> Surely where code has a cast to `void*` and then later back to some other pointer type
>
> The question was only about the first part, casting to void*, not casting back.

Yea, I get that.  My point is that I'm not sure that it makes sense to decouple the first part and the second part, when thinking about safety, and the programmer's responsibility to manually verify it.
December 16, 2019
On 12/13/19 3:05 AM, Andrej Mitrovic wrote:
> I recently got to thinking about a code snippet. The following doesn't compile, because casting to a void* is considered unsafe:
> 
> -----
> import std.stdio;
> 
> class C
> {
>      void foo() @safe
>      {
>          writeln("%s: C.foo()", cast(void*)this);
>      }
> }
> 
> void main()
> {
> }
> -----
> 
>> test.d(7): Error: cast from `test.C` to `void*` not allowed in safe code
> 
> However, I don't see this cast as being unsafe. Casting a class object to a `void*` doesn't break the type system by itself. You cannot assign a `void*` to any other pointer type without an additional cast, and that additional cast would be the unsafe one. Additionally, you cannot reference a `void*`, so as far as I can see it's fairly safe to use in @safe code.
> 
> Wouldn't it make sense to allow casting reference types to `void*` in @safe code? Are there edge-cases I haven't considered?
> 

Yes. Implicit casting to void * from another pointer type is allowed. i.e. this code compiles in safe mode:

int *p = new int;
void *v = p;

Class references are no different than pointers in safe code (rebindable, can be null, no pointer arithmetic), and they are even more likely to live on the heap, which makes them even safer than the above.

Please file an issue if not one already.

-Steve
December 16, 2019
On 12/14/19 6:48 PM, Joseph Rushton Wakeling wrote:
> On Saturday, 14 December 2019 at 20:53:49 UTC, Dennis wrote:
>>> 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.
> 
> No, it is not @safe, and for good reason.  When you cast an integral value to a `void*` that value gets reinterpreted as a memory address.  But you have absolutely no right to assume that it is a valid memory address.

It's not technically unsafe, but is prone to safety problems. It's true that a void * is completely unusable in safe code. But loads of code has both safe and unsafe parts.

Not to mention that the GC makes different decisions based on whether a type contains a pointer or not. I think we are reasonably fine leaving a rule in place to prevent casting from a non reference type to a void *.

However, a class reference is very similar to a pointer, we should allow that cast (to void * only).

> 
> Things like this are WHY the spec has the rule that one cannot cast from a non-pointer type to `void*` in code marked @safe.

The spec rule is likely not focused on void * or classes, but really something like:

auto p = cast(int*) 8;

which then can be used in safe code to do damage:

*p = 5;

-Steve
1 2 3
Next ›   Last »