Why use a DFA instead of DIP1000?

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Mon Sep 15 08:58:08 UTC 2025


On 14/09/2025 7:58 AM, kdevel wrote:
> On Saturday, 13 September 2025 at 15:43:27 UTC, Richard (Rikki) Andrew 
> Cattermole wrote:
>> [...]
>>> I thought that the intent of the original code
>>>
>>> ```d
>>> int* ptr;
>>>
>>> void func(bool b, scope int* p) @safe {
>>>    assert(!b);
>>>
>>>    if (b) {
>>>      ptr = p; // Error: scope variable `p` assigned to global 
>>> variable `ptr`
>>>    }
>>> }
>>> ```
>>>
>>> was to show that there is some code-block
>>>
>>> ```d
>>>      ptr = p; // Error: scope variable `p` assigned to global 
>>> variable `ptr`
>>> ```
>>>
>>> which is never executed regardless of the value of `b`.
>>
>> Half right.
>>
>> There is a code block that will never be executed, it is because of 
>> variable b's state is known to prevent that code block from execution.
> 
> Then it is dead code that should be manually removed? Isn't that the 
> problem here? The compiler correctly complains about invalid code, this 
> is not a false positive, even if that code is never executed.
> 
> If I want code not to be executed I comment it out or delete it.

In practice, when this is applied people don't complain about it.

https://github.com/dlang/dmd/issues/21859

Compiles with full D, but not -betterC (which does the extra check 
without the culling which is a bug).

```d
void func() nothrow {
     if (0) {
      	 throw new Exception("");  // Error: cannot use `throw` 
statements with -betterC
     }
}
```

When both DFA and Control Flow graph (CFG) processing is working 
correctly its a well loved compiler feature. You don't know its there 
unless something has gone wrong like in the above code.

When I learned how nothrow inference worked I was really impressed with 
how it was applying CFG analysis. I did not expect the frontend to be 
doing it.



More information about the Digitalmars-d mailing list