andrewducker: (Default)
andrewducker ([personal profile] andrewducker) wrote2010-02-11 03:11 pm

Thinking about code

  If I have a method:
int DoSomething(string someStuff)
{
  //Do Stuff
  return 42;
}
then effectively I have an unnamed variable that gets set by the return statement, yes?

That being the case, wouldn't it be in some ways clearer to have an explicit, named, variable that gets set instead?

int DoSomething(string someStuff)
{
  //Do Stuff
  returnValue = 42;
}

where "returnValue" is a keyword that's used to return the value.

As it is I frequently end up with code that creates (or sets) a variable at various points through the code just so it can be returned at the end.  Making this an explicit part of the language just makes sense to me.

I assume there are languages out there that do this.

[identity profile] skington.livejournal.com 2010-02-11 03:50 pm (UTC)(link)
Why do you care, as the called function? It ends up on the stack or heap, your job is done.

As the calling function, you'll assign the result to a variable of your choice (or not assign it at all, if you can do that sort of thing and you only care whether the function returned e.g. a true value, or you'll pass the value to a switch statement).

[identity profile] skington.livejournal.com 2010-02-11 03:57 pm (UTC)(link)
So you basically want exactly the same as the return keyword, except you can call it at any time without actually returning. So what if you want to return part-way through your function? Do you now have to use two keywords?

[identity profile] jsburbidge.livejournal.com 2010-02-11 04:45 pm (UTC)(link)
In a decent optimising compiler, a constant value return isn't "put" anywhere except outside the function, where it is used as a precompiled/hardcoded value (which may in itself be used in a context allowing further precompilation reducing runtime overhead). In particular, it may never be put on the stack to be returned, although it may be used to set/initialize a value in the calling context.

As an extreme example, imagine that the function is called in the context

if (DoSomething(x)) {
... stuff
} else {
... other stuff
}

The compiler should never actually store "42" but will instead elide the else branch of the test.

[identity profile] call-waiting.livejournal.com 2010-02-11 06:54 pm (UTC)(link)
Only if the compiler does interprocedural analysis, which not many do. Alternatively, it could be inlined, but most will only do so if it's in the same compilation unit, and you ramp up the optimiser setting sufficiently.

[identity profile] jsburbidge.livejournal.com 2010-02-11 07:24 pm (UTC)(link)
I was thinking of the "same compilation unit" case, in fact. I was also deliberately ignoring the fact that the obvious reason for returning a constant is the implementation of an interface (C++: of a virtual function) for a family of functions which may return different values, in which case obviously there will be no optimisation when the interface / base class is used.

One variant of this optimisation which is more common, though, is returning an object by value and assigning to a class constructed at that point:

Foo x = somefunction();

For some compilers the object will be constructed once, at the higher level, and there will be no temporary variable of that type in the returned data on the stack (which will be data required to initialize the object -- the difference obviously being that operations in the constructor are called only once).