Warn about using the GC

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Sun Jan 14 19:53:21 UTC 2024


On 15/01/2024 8:23 AM, Walter Bright wrote:
> On 1/14/2024 4:47 AM, Richard (Rikki) Andrew Cattermole wrote:
>> ```d
>> void func(void delegate() @nogc del) @nogc;
>> ```
>>
>> Basically if you pass in a delegate that does not have ``@nogc``, the 
>> ``@nogc`` on the function gets removed.
>>
>> The function body will of course be typed checked as if it did have 
>> ``@nogc``.
>>
>> I want this to be the default, although Timon wants it to be much more 
>> configurable so you can pick and choose per parameter (again not 
>> mutually exclusive things!).
> 
> The trouble with having a nogc function calling a gc delegate is it 
> makes the nogc function a gc function. (If the nogc function does not 
> actually call the gc delegate, but just stores it somewhere, that works 
> fine.) If the nogc was silently removed, wouldn't that be very 
> surprising behavior?

I think that we are looking at this inversely to each other.

Storing such a function pointer is itself a big problem, for instance it 
could create a time bomb that you cannot predict. But calling it has no 
direct program security issues (actual term in type theory!).

``@nogc`` doesn't affect codegen. But when it gets called on say a 
non-registered thread, could crash the program.

So as long as the caller is still in the call stack while the ``@nogc`` 
code has access to it, is perfectly fine from a code security standpoint.

Whilst code security isn't a concern, performance could be. It is up to 
the caller to ensure GC is disabled if it needs to be. This may be the 
primary side effect that could be surprising. Which of course could be 
determined by using a profiler.

So in other words, the worst case scenario for calling it means you need 
to use a profiler if you care about it being slow. Which is already the 
recommended course of action.

On the other hand, storing it has as its worse case scenario program 
termination and data corruption.

As for is this surprising? Think of it this way. The caller doesn't have 
a guarantee. It does not care if what it calls has it. So why should the 
compiler create an error for something the caller never cared about in 
the first place when it could be removed?

> There is another way, though. In @system code, the gc delegate can be 
> forcibly cast to be @nogc (as far as the type system is concerned - it 
> doesn't change the behavior of the delegate).
> 
> Such forcible casting can be done with any of the attributes. However, 
> as this subverts the type system, the correctness of it would be 
> entirely up to the user.
> 
> D has overrides like this because it's a systems programming language.

Correctness is built upon the ability to reason the logic about something.

Casting removes the ability to reason, therefore correctness goes away too.

However, if we instead make the compiler smarter and give it the ability 
to reason the removal of guarantees, now we get to keep correctness 
whilst making the code much easier to work with.

Guarantees can be removed, they cannot be added without a proof.



More information about the Digitalmars-d mailing list