how much "real-life" code can be marked @safe ?

tsbockman thomas.bockman at gmail.com
Fri Jul 2 22:08:31 UTC 2021


(Responding out of order:)

On Friday, 2 July 2021 at 00:26:52 UTC, someone wrote:
> But when you start attempting to declare @safe chunks of code 
> that actually DO things ... well, it seems end-of-the-story.

If you find yourself unable to get real work done in `@safe` 
code, this is almost certainly a sign of one of the following 
problems:

0) You don't fully understand the purpose and valid use of any or 
all of the `@trusted`, `inout`, `scope`, and `return` annotations.

1) Your code is avoiding use of the garbage collector, and/or 
does not have `-dip1000` enabled. (`@safe` is still quite useful 
without the garbage collector, but even with `-dip1000` you'll 
still need a lot of `@trusted` code.)

2) You have at least one dependency that isn't correctly designed 
for use with `@safe`.

As long as you're willing to use the garbage collector, almost 
all algorithms can be expressed in an efficient `@safe` way, 
**but** this sometimes requires knowledge of several advanced 
features of D, and how and when to combine them.

> but no castings are allowed with @safe

That is simply not true. Many explicit casts are `@safe`, as are 
nearly all implicit casts.

Casting away `const` or `immutable` is `@system`, but should 
hardly ever be necessary if you understand how to write 
constructors correctly (see below), and use `inout` appropriately.

Many reinterpret casts are also illegal, but `union` and `class` 
provide `@safe` ways of achieving the same goals for the common 
cases.

> - almost all this() constructors are a no-go providing you do 
> something in-between with the parameters until you assign them 
> back to the target variables;

Constructors can be `@safe`, but you have to understand how they 
work in D:

The key difficulty is that what appears to be the first 
"assignment" to each field in a constructor actually constructs 
that field, instead. Subsequent assignments really are 
assignments.

So, when constructing a `const` object each field can only be 
"assigned" once, because the fields are also `const`, even in the 
object's constructor. If you need to do complex calculations to 
determine field values, use temporary variables and `static` 
helper functions until you get the final value, and then 
unconditionally assign that value to a field *once*.

**TLDR**; You probably don't understand how to use `@safe` 
correctly. (Most people don't; the rules are complicated and 
non-obvious.)

Post some example code that you think can't be `@safe`, and I can 
probably show you how to fix it, unless it involves manual memory 
management or an incompatible dependency. Even then, the 
non-`@safe` code can often be isolated behind an `@trusted` API.


More information about the Digitalmars-d-learn mailing list