0

I use "reference" term here like in C++ world, not like in C# (for example). I use non-C++ syntax on purpose -- this is general question, not about this particular implementation.

Starting something like C++ afresh I would like to make rules and validation in order to prevent a case when reference outlives its source. For example this looks like a valid usage:

def foo(x ref int) ref int
    return x;
end

But this is wrong:

def bar() ref int
    x int = 5;
    return x;
end

because in bar example x is put on stack and when reference to it is returned this stack is already gone.

I didn't so far find the analysis algorithm description so that is why I am asking -- what to allow (for example defining parameters as references), and how to check when the usage is abused creating dangling references?

11
  • 1
    Be careful when saying things like "is put on stack." In languages like C# and Java, the "stack" is an implementation detail. In those languages, you're not supposed to know or care whether items like x go onto the stack or the heap, and ultimately this is a scope problem, not a stack problem. Commented Jan 9, 2018 at 17:55
  • I suspect that your declaration in the second code example isn't even possible in C#; it would be a compile error. int in C# is a primitive type, not an object (reference), and it's perfectly acceptable to create an int and return it (by value) in C#. Commented Jan 9, 2018 at 18:01
  • 4
    Your examples are simple and can be solved with an escape analysis. But there can be far more tricky constellations that are not solvable with a C++-style type system (the compiler would have to solve the halting problem). Take a very good look at Rust's ownership tracking instead: every reference is parametrized by a lifetime. The type system can check that no reference can outlive the lifetime of it's object.
    – amon
    Commented Jan 9, 2018 at 18:32
  • 1
    Any automatic local variable will go out of scope as or before function return, so a reference to one shouldn't be returned as in theory it might already be destroyed. Parameters will go out of scope as well, but if the parameter is a ref parameter, then it is essentially bound to some variable passed by the caller, who controls its scope.
    – Erik Eidt
    Commented Jan 9, 2018 at 19:21
  • 1
    Have you looked at Rust? It is a language with exactly the design goals you state. Commented Jan 10, 2018 at 14:04

2 Answers 2

1

What you are looking for is called escape analysis, and like pretty much all static analysis of programs is equivalent to solving the Halting Problem.

It can only be solved in restricted circumstances, in particular, it is much easier to solve if the language is specifically designed in such a way as to restrict the kinds of programs that can be written to that subset which is amenable to static escape analysis.

1
  • 1
    Ah the Halting Problem. Pretty much any mildly interesting fact you could ever hope to know about a program however insignificant is impossible to generalize.
    – Neil
    Commented Jan 10, 2018 at 10:46
0

If you are creating a low-level language, there is nothing you can do to stop dangling pointers, null pointers, circular references, and memory leaks. The best you can do is provide a memory debugger to help track down bugs.

On the other hand, if you are creating a higher-level language, then you can stop all these problems by not allowing programmers direct access to pointers. An example of this is the POSIX ln command. A user cannot use it to hard link directories; only the root user can. A user simply cannot any of the problems with pointers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.