(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:
-
You don't fully understand the purpose and valid use of any or all of the @trusted
, inout
, scope
, and return
annotations.
-
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.)
-
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.