@safe and null dereferencing

Adrian Matoga via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 27 10:33:22 PDT 2017


On Thursday, 27 July 2017 at 15:03:02 UTC, Steven Schveighoffer 
wrote:
> Inside the thread for adding @safe/@trusted attributes to OS 
> functions, it has come to light that @safe has conflicting 
> rules.
>
> For the definition of safe, it says:
>
> "Safe functions are functions that are statically checked to 
> exhibit no possibility of undefined behavior."
>
> In the definition of @trusted, it says:
>
> "Trusted functions are guaranteed by the programmer to not 
> exhibit any undefined behavior if called by a safe function."
>
> Yet, safe functions allow dereferencing of null pointers. 
> Example:
>
> void foo() @safe
> {
>    int *x;
>    *x = 5;
> }
>
> There are various places on the forum where Walter argues that 
> null pointer dereferencing should cause a segmentation fault 
> (or crash) and is checked by the hardware/OS. Therefore, 
> checking for null pointers before any dereferencing would be a 
> waste of cycles.
>
> However, there do exist places where dereferencing null may NOT 
> cause a segmentation fault. For example, see this post by 
> Moritz Maxeiner: 
> https://forum.dlang.org/post/udkdqogtrvanhbotdoik@forum.dlang.org
>
> In such cases, the compiled program can have no knowledge that 
> the zero page is mapped somehow. There is no way to prevent it, 
> or guarantee it during compilation.
>
> It's also worth noting that C/C++ identifies null dereferencing 
> as undefined behavior. So if we are being completely pedantic, 
> we could say that no C/C++ code could be marked safe if there 
> is a possibility that a null pointer would be dereferenced.
>
> The way I see it, we have 2 options. First, we can disallow 
> null pointer dereferencing in @safe code. This would be hugely 
> disruptive. We may not have to instrument all @safe code with 
> null checks, we could do it with flow analysis, and assuming 
> that all pointers passed into a @safe function are not null. 
> But it would likely disallow a lot of existing @safe code.
>
> The other option is to explicitly state what happens in such 
> cases. I would opt for this second option, as the likelihood of 
> these situations is very low.
>
> If we were to update the spec to take this into account, how 
> would it look?
>
> A possibility:
>
> "@safe D does not support platforms or processes where 
> dereferencing a null pointer does not crash the program. In 
> such situations, dereferencing null is not defined, and @safe 
> code will not prevent this from happening."
>
> In terms of not marking C/C++ code safe, I am not convinced we 
> need to go that far, but it's not as horrible a prospect as 
> having to unmark D @safe code that might dereference null.
>
> Thoughts?
>
> -Steve

Why can't we just make the compiler insert null checks in @safe 
code? We can afford bounds checking even in @system -O -release. 
C++ can afford null check upon executing an std::function. The 
pointer would most likely be in a register anyway, and the 
conditional branch would almost always not be taken, so the cost 
of that check would be barely measurable. Moreover, the compiler 
can elide the check e.g. if the access via pointer is made in a 
loop in which the pointer doesn't change. And if you prove that 
this tiny little check ruins performance of your code, there's 
@trusted to help you.



More information about the Digitalmars-d mailing list