Memory safe in D
Steven Schveighoffer
schveiguy at gmail.com
Wed Mar 13 19:58:24 UTC 2024
On Wednesday, 13 March 2024 at 19:36:01 UTC, Alex wrote:
> On Wednesday, 13 March 2024 at 18:20:12 UTC, Steven
> Schveighoffer wrote:
>> - The path D takes is, let the hardware solve it.
>> - The path Java takes is to instrument dereferences on
>> possibly-null variables and throw an exception if it's null.
>> - The path many other languages take is to force you to
>> validate it's not null before using it.
>
> Rust doesn't allow null references at all (exclude unsafe
> code). It is one more alternative path.
Then "optional" types, basically the same thing. Null is a memory
safe "invalid thing".
The thing I'm getting at is -- if you have something that doesn't
exist, but is supposed to exist, then you have to deal with it.
How you deal with it is where the tradeoffs come in.
The basic building block that all memory-safe language tools are
built on is -- you should not be able to use invalid memory. null
pointers which halt the program are a flavor of that.
>> For the other languages, you are forced to validate something
>> is null or not null. This has the advantage that certain
>> classes of bugs can be avoided at compile time, and in many
>> cases, the code can be clearer where null pointers might
>> exist. But the cost is that you may be forced to validate
>> something that is obvious to the developer (but not the
>> compiler). It adds to the tediousness of the language.
>
> On the other side with this approach developer can choose
> between nullable type and non-nullable. If he choose nullable
> type he really have to do checks. But for non-nullable type he
> can work completely safety without any checks. As I know Kotlin
> encourages using non-nullable types wherever possible.
The checks have to come somewhere.
If you have a value that is of *unknown* validity, and you want
to ensure it's valid, you need a check. We have different flavors
of:
* automated checks
* how the checks are handled if failure occurs
* checks that you are forced to perform
* how long such checks are enforced by the compiler (e.g., flow
analysis, building into the type the validity).
Building non-null into the type indeed means as long as you have
that type, you don't have to check. But to get it into that type,
if you started with a possibly-invalid value, *somewhere* you had
to do a check.
Consider an array/vector of items in Rust. And an index. When you
index that vector, the compiler has no idea what that index is.
It must validate the index before dereferencing the element. This
is a check, and the handling of it is defined by the language.
Having a possibly-null pointer is no different. D defines that in
safe code, a pointer will be valid or null. The "check" occurs on
use, and is performed by the hardware.
This is in *stark* contrast to having a possibly-invalid pointer
to non-null memory (e.g. dangling or buffer overflow). Those
should never occur.
-Steve
More information about the Digitalmars-d
mailing list