memory safety checks and trust

Steven Schveighoffer schveiguy at gmail.com
Wed Apr 15 15:11:28 UTC 2020


On 4/15/20 2:12 AM, Walter Bright wrote:
> On 4/14/2020 1:40 PM, Steven Schveighoffer wrote:
>> Also, this compiles just fine, and gives you the stack pointer value:
>>
>> size_t stackPtr() @system
>> {
>>    int i;
>>    return cast(size_t)&i;
>> }
> 
> Yup. I also gave workarounds to Adam's example.

Of course. There are workarounds to all these issues. The question then 
becomes, is the inconsistency for this particular restriction worth the 
annoyance it causes to work around it.

The answer is subjective, as always. IMO, fetching the stack pointer is 
something that just isn't ever a requirement for code. It's such a 
specialized need that the annoyance it causes is worth all the memory 
problems it prevents when people accidentally return stack references. 
Maybe that's just my code, maybe everyone else needs to fetch the stack 
pointer in their code. But I didn't think that was the case.

On the other hand, using heap data is pretty common in my code, and 
occasionally I might stick a reference to stack data in there. If I am 
doing it responsibly, there is no harm. The compiler might make me jump 
through some annoyance hoops, but it's possible to do.

So we have to draw a line, an arbitrary line, that says "everything like 
this is going to require some workaround, everything else, well it's 
@system code, you got what you signed up for". My line is that returning 
stack pointers, if provable, is more often than not an error, and I 
would like to be reminded of it from the compiler. Putting stack data 
into heap blocks, is already not consistently flagged, so I don't think 
it's saving much to have this annoyance available.

But if the compiler is going to be annoying, be annoying according to a 
plan, not just random annoyance.

>> I can do this too, apparently since it's a TLS array and not a heap 
>> array, totes ok!
>>
>> int*[1] arr;
>>
>> void bar()
>> {
>>      int i;
>>      arr[0] = &i;
>> }
> 
> Ironically, I argue for consistency with "safe by default" and you argue 
> for special cases, and here the reverse.

There are different levels of consistency. If you have a reasonable 
rule, then be consistent in that rule. It might make you have to do some 
extra workarounds to use the language, but the result is that you should 
be a better programmer, and you have a rationale to point at for why 
things are the way they are.

I'll take for example the rule that if(cond); is disallowed. It's a 
wonderful rule, but totally not consistent with the language (I can 
write empty statements in most other places). BUT it's such a common 
mistake that it's worth the annoyance. It's caught bugs for me many many 
times.

However, what if while(cond); was allowed? That kind of inconsistency 
doesn't make sense. It's inconsistent to disallow empty statements for 
an if block, but allow them for while blocks. Arguing that people would 
want consistency with while statements but not if statements is hard to 
justify.

In the safe debate, the problem is simply that code that compiles today 
and is @system will compile tomorrow and be @safe, without ANY checking 
or any deprecation. This destroys everything that @safe has been built upon.

Ironically, what I'm asking for is consistency with existing code, and 
you are arguing to make an exception that extern(C) @system functions 
compile should silently convert to @safe functions without warning. We 
just cannot change the meaning of all code without warning people or 
causing an error.

If we didn't have existing code that's extern(C) then the debate would 
be entirely different. It would be a new thing, and it would be a 
legitimate position to have extern(C) prototypes safe by default.

I'll note that I proposed an alteration that has received zero responses 
that I think would solve all those concerns:

https://forum.dlang.org/post/r6kvm4$1vq5$1@digitalmars.com

> 
> But be careful, you may talk me into disallowing these cases, too :-/
> 

If you did, it would at LEAST be reasonable! At least the rule would be 
consistent. So I would be fine with it! As Adam says, there is no rhyme 
or reason for this one rule vs. the allowances for other code, so 
there's no predictability as to when D might somehow decide what you did 
was not correct.

Ruling by whim is not as understandable as providing clear and 
consistent rules to base changes on.

-Steve


More information about the Digitalmars-d mailing list