Memory safe in D
Richard (Rikki) Andrew Cattermole
richard at cattermole.co.nz
Mon Mar 11 20:43:02 UTC 2024
On 12/03/2024 9:39 AM, bachmeier wrote:
> On Monday, 11 March 2024 at 19:22:54 UTC, Richard (Rikki) Andrew
> Cattermole wrote:
>> On 12/03/2024 4:31 AM, bachmeier wrote:
>>> On Monday, 11 March 2024 at 08:48:47 UTC, Richard (Rikki) Andrew
>>> Cattermole wrote:
>>>> On 11/03/2024 9:16 PM, Alex wrote:
>>>>> So I don't see any errors or warnings from compiler when I use
>>>>> uninitialized variable |a| and don't see any exception with
>>>>> backtrace in runtime (application is build in debug mode).
>>>>>
>>>>> Is it expected behavior? Looks like it is not very safe approach
>>>>> and can lead to very unpleasant memory errors...
>>>>
>>>> This is expected behavior.
>>>>
>>>> The variable a was default initialized to null.
>>>>
>>>> D has not got type state analysis as part of it, so it cannot detect
>>>> this situation and cause an error.
>>>>
>>>> It is at the top of my todo list for memory safety research for D,
>>>> as the IR it requires enables other analysis and provides a
>>>> framework for it to exist in.
>>>
>>> Rather than doing that, couldn't the compiler say `A a;` is not valid
>>> inside `@safe`?
>>
>> One of the improvements for type state analysis I want to make is for
>> methods:
>>
>> ```d
>> class Foo {
>> void func(this'nonnull);
>> }
>> ```
>>
>> Instead of:
>>
>> ```d
>> class Foo {
>> void func(this'reachable);
>> }
>> ```
>>
>> That'll catch it when you try to call something.
>>
>> However I'm not sure if disallowing null entering is a great idea, its
>> going to enter through other methods so you might as well embrace
>> catching that as well.
>
> What I've never understood is the valid use case for `A a;` that would
> justify that line compiling. I don't do much with classes, but the same
> thing comes about with structs. Why would it make sense to write code
> like this, particularly if you've marked it @safe?
>
> ```
> struct Foo {
> double n;
> string s = string.init;
> }
>
> Foo * f;
> // Crashes
> writeln(f.n);
>
> Foo * f = void;
> // Doesn't crash but gives wrong output
> writeln(f.n);
>
> Foo * g;
> // Crashes
> g.n = 3.3;
>
> Foo * g = void;
> g.n = 3.3;
> // Correct output
> writeln(g.n);
> // Crashes
> writeln(g.s);
> ```
Like that? No.
You may be setting the variable based upon some condition and then
passing the result into a function.
Null may be a valid behavior for that function.
More information about the Digitalmars-d
mailing list