how much "real-life" code can be marked @safe ?
tsbockman
thomas.bockman at gmail.com
Sat Jul 3 20:09:56 UTC 2021
On Saturday, 3 July 2021 at 16:06:33 UTC, Alexandru Ermicioi
wrote:
> 3. An edge case. Ex: You need to mutate some data and then
> assume it is immutable in a constructor.
Can you give a valid example where that is necessary? The main
examples that I can think of either can be `@safe` with the right
API, or are motivated by a desire to avoid the GC and/or
druntime, thus falling under (1).
> 4. Functionality that doesn't account for @safe/immutable or
> any other features when it can in standard library.
True, although it's just another example of my point (2). The
standard library and druntime are dependencies, too...
> Take for example array.dup, there is no inout alternative for
> it,
> and you're pretty much stuck with trusted code, when you'd like
> to dup an array that is inout.
`inout` is usually just a convenient way to use one
implementation to handle mutable, `const` and `immutable` cases.
In those rare cases where `inout` itself won't work, it is almost
always possible to accomplish the same thing using `template
this` or separate overloads:
```D
import std.traits : Unqual, CopyConstness;
struct A {
int*[] arr;
this(this This, Arr)(Arr arr) scope pure @safe nothrow
if(is(Arr : E[], E) && is(E : CopyConstness!(This,
Unqual!E)))
{
this.arr = arr.dup;
}
}
void main()
{
A ma = new int*[5];
const(A) ca = new const(int*[3]);
const(A) ia = new immutable(int*[4]);
}
```
Again, it's certainly not obvious how to do this, or why it is
necessary, but it is *possible*.
The one exception here is when the array is already typed `inout`
before it is passed to the constructor. But, that's an example of
(2) since this logic applies transitively throughout the call
stack: if you need to call `dup` anywhere, don't erase the
constness with `inout`.
More information about the Digitalmars-d-learn
mailing list