6

There's an advice in C++: "Never Return a Reference to a Local Object", as below quoted from "C++ Primer":

"There's one crucially important thing to understand about returning a reference: Never return a reference to a local variable.

"When a function completes, the storage in which the local objects were allocated is freed. A reference to a local object refers to undefined memory after the function terminates. Consider the following function:

 // Disaster: Function returns a reference to a local object
 const string &manip(const string& s)
 {
      string ret = s;
      // transform ret in some way
      return ret; // Wrong: Returning reference to a local object!
 }

"This function will fail at run time because it returns a reference to a local object. When the function ends, the storage in which ret resides is freed. The return value refers to memory that is no longer available to the program."

Question: so does this still apply to C#? or it doesn't matter as GC is introduced?

athos
  • 6,120
  • 5
  • 51
  • 95
  • 1
    I disagree with "this function will fail at run time.". It *may* fail, and is unsafe. But in many cases, the storage will be available for a time after the return, Often making this kind of problem difficult to debug. – abelenky Jul 03 '11 at 16:03
  • 1
    abelenky is correct; there is no guarantee whatsoever that anything there will fail, ever. It is not a requirement that the storage be "freed", whatever that means. A program that does this could work the way you want -- you might get lucky -- or, it could bring the entire system crashing to a halt, or it could erase your hard disk. It could do *anything*. See http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 for more thoughts. – Eric Lippert Jul 05 '11 at 19:41

2 Answers2

5

It is not possible to return references to local variables in .NET

See: Why doesn't C# support the return of references?

See also: Ref returns and ref locals (Eric Lippert's Blog)

Community
  • 1
  • 1
dtb
  • 213,145
  • 36
  • 401
  • 431
  • This is somewhat wrong misleading. You cannot return *by reference* but you can of course return *a* reference. This reference won’t refer to a local object though. – Konrad Rudolph Jul 03 '11 at 15:50
  • @Konrad Rudolph: Huh? Quote: "references to local variables". So something like `ref int Foo() { int x = 5; return ref x; }`. That's not possible. And there are no "local objects" in .NET, just local variables containing references to objects managed by the CLR. – dtb Jul 03 '11 at 15:52
  • I know. I still think this could be formulated more clearly since it easily misleads, instead of just linking elsewhere. Note that despite this criticism I’ve upvoted your answer … – Konrad Rudolph Jul 03 '11 at 15:55
4

C# language does not allow that. In C# there are two very different kinds of references:

1) References to classes and similar "Reference Types". Since the target of these is always allocated on the heap the reference will always be valid after returning.

2) References to local variables/parameters. Called managed references in the CLR. For example:

void DoSomething(ref int i, ref object o)

You can't declare a return type that uses this kind of reference in C# (The CLR itself offers some restricted support for that). Since you can only pass them to other functions as parameters, can't store them in fields, and can't return them it's impossible to keep one of those around after the function returns. So once again using them is safe.

Basically in C# you can only use them for pass-by-reference parameters. Note that you can have a ref to a reference type variable(ref object o) but not a reference to a reference ref ref int i.

Eric Lippert posted a blog entry on this kind of reference a few days ago detailing the problems with ref return values: Ref returns and ref locals

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262