Escaping objects and what is escape analysis modelling anyway?
Dukc
ajieskola at gmail.com
Mon Jul 27 16:27:31 UTC 2026
On Saturday, 25 July 2026 at 14:52:30 UTC, Richard (Rikki) Andrew
Cattermole wrote:
> An example of this is you can utilize conditionals to model
> relationships:
>
> ```d
> int* returnCond(bool cond, int* obj)
> {
> if (cond)
> return null;
> else
> return obj;
> }
> ```
>
> So this could have a graph that looks like:
>
> ```
> [
> ( if (params[0] == true)
> return = null
> ),
> ( if (params[0] == false)
> return = params[1]
> )
> ]
> ```
Probably the compiler can't rely on this, other than for
optimisations, unless we'll also have attributes to specify this
manually. Otherwise `returnCond` couldn't be put to a `.di` file,
nor could you type a function pointer so that you could call it
like this.
> Do the following functions have the same relationship between
> their function parameter and return value?
>
> ```d
> int** rel1(int** param) => param;
> int** rel2(ref int* param) => ¶m;
> ```
>
> Yes and no.
> A big part of the problem here is `rel2`, you can look at it
> and think oh I know it's got two cells, just like `rel1`!
> And that is true as far as what you should have access to.
> But its not; it's actually the same parameter as the first
> `rel1`, but you've specified that the first indirection is
> guaranteed to be non-null and should be ignored.
> This gives you three cells, with the first being hidden to the
> user, and the second being automatically dereferenced.
> That is storage of the parameter, pointer to `int*` that was
> passed in, and then the `int*` itself.
>
> Knowing this allows us to model function calls of functions
> like these and know that the assert will hold true during
> compilation
I'm afraid you have misanalysed this and might be basing your
escape analyser on sand.
If this was C++ you would be right, since calling a C++ function
with a `&` reference to null is undefined behaviour. However, the
D spec doesn't say so (nor could it, since it's allowed in
`@safe`. Could in principle be implementation-defined, though),
and in fact a `ref` variable residing at null will [not even
crash](https://forum.dlang.org/post/flutpcacmrxoqmnshrrw@forum.dlang.org) if you don't use it anyhow. It seems likely this is the intended behaviour, though I don't have a confirmation.
> The `rel1` and `rel2` have two separate attributes `return` and
> `return ref`.
> And `rel3` has another `return scope ref` on top of that.
>
> When really the differentiation is just: "am I returning the
> outermost object?"
>
> This is not the only issue with DIP1000, but it's a pretty big
> one.
> That has led to the D community not understanding how or why
> DIP1000 works the way that it does.
> It's not how the attributes are presented; it's what the
> attributes are representing.
This is certainly one way to view it. However, the differentation
DIP1000 is making isn't any more complex: either you're
(potentially) returning the `ref` address, or the address inside
the variable. Two distinct cases, no more, just like in your
formulation.
So I still think the DIP1000 confusion about the return attribute
is mostly in it's representation (when does `return` mean `return
ref`, when `return scope`), not in the very idea. Yours would be
about as hard to understand.
More information about the Digitalmars-d
mailing list