Path: utzoo!attcan!utgpu!watmath!att!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!ginosko!uunet!zephyr.ens.tek.com!tekcrl!tekfdi!videovax!bart
From: bart@videovax.tv.Tek.com (Bart Massey)
Newsgroups: comp.lang.c++
Subject: proposed NRV syntax change (Re: named return values) (LONG)
Message-ID: <5522@videovax.tv.Tek.com>
Date: 9 Aug 89 23:38:16 GMT
References: <1826@cmx.npac.syr.edu> <26302@shemp.CS.UCLA.EDU> <6444@columbia.edu> <26314@shemp.CS.UCLA.EDU>
Reply-To: bart@videovax.tv.tek.com (Bart Massey)
Organization: Tektronix TV Measurement Systems, Beaverton OR
Lines: 55

My biggest beef with NRVs is that I've used them in Pascal and really hated
them there -- it's really nice for the compiler to be able to warn you that
your function may fall off the end without returning a value, and most
Pascal compilers aren't that smart.  It just so happens that I'm the only
programmer in the world dumb enough to forget to return a value from a
function, but... :-) :-)

Of course, as Doug Lea commented, the situation is different in C++, where
you will return something that is properly constructed instead of random
garbage if you fall off the end by accident.  But it's not clear that this
is better from a correctness point of view -- the compiler now has no idea
whether you meant to fall off the end or not, and thus *should not* warn
about it.  In fact, it's worse than that, since you may have altered the
object but left it in the "wrong" state before falling off.

I guess I've always sort of thought of the C/lint requirement of an explicit
return value at end-of-function as an assertion that I, the programmer,
haven't forgotten about that important case, and kind of liked it for that
reason.  NRVs as currently implemented seem to me to break that model.

I guess what I would like is to allow NRVs, but still require the explicit
return statement.  If the return value happens to be the NRV, then the
compiler may optimize that case.  Any other return value is treated as
usual.  To use Doug Lea's example,

X iota_nrv() return x          // x is the name of the X we may be returning
{
  if( Xsize == -1 ) {	       // some special case
      X *y;
      magic_construct( y );    // some magic construction
      return *y;                // return a copy via X(X&)
  }
  for (int i=0; i