Topic: Rationale behind disallowal of non-const reference to rvalue


Author: davew@trigati.cs.haverford.edu (David G. Wonnacott)
Date: 1996/03/28
Raw View
[Moderator's note: this article is crossposted to comp.std.c++ and
gnu.g++.help, and followups have been set to comp.std.c++.  Please be
aware of what newsgroup your article is going to when you respond.  mha]

I am looking for an explanation for the rationale behind the decision
of the standards committee to disallow the binding of a non-const
reference to an rvalue.  I assume this has been discussed to death
here before, but I haven't been able to find it in a FAQ; I'd be happy
with a reference to another document rather than a full reply here.

The only answer I've seen for this question before is that it is
disallowed because the reference may outlive the rvalue it refers to.
But isn't this just as much a risk for const references as non-const?
I can't see why non-const references should be illegal when const
references are legal.

One other question (for the g++ group) - is the current plan for G++
to eventually give an error, rather than a warning, when this rule is
broken?  If so, is there any possibility of a switch to disable this?



A detailed explanation of my question, and references, follow.  Those
of you who have seen this before may want to skip the rest.

Paragraph 2 of Section 13.3.3.1.4 of the April draft of the C++
standard (http://www.cygnus.com/misc/wp/draft/, repeated below for
convenience) states that the following is illegal (at least as far as
I understand it):

 class foo { ... };
 foo f1();
 int f2(foo &f);

 void test()
 {
  int i = f2(f1());
 }

g++ agrees with my reading, giving the following warning for this code:

  In function `void test()':
  warning: initialization of non-const `foo &' from rvalue `foo'
  warning: in passing argument 1 of `f2(foo &)'

However, if f2 is changed to "foo f2(const foo &f);", there is no
problem (either according to my reading of the standard or to g++).

So - my questions are:

1) What can go wrong with f2 as it is written that can't go wrong with
f2 if it took a const foo &?  I know that the reference could out-live
the compiler generated temporary - but that can happen with the
"legal" code as well.

2) If there is no error that would be prevented by the introduction of
const, why is the code legal with const and not without?  Just because
nobody thought it would be useful to do this?  We do it all over the
place in the Omega Library (http://www.cs.umd.edu/projects/omega) - we
want to perform an operation that extracts information from the
argument of f2, and return the extracted information.  Whats the big
deal if this operation may have a side effect?

Puzzled,
 Dave Wonnacott
 davew@cs.haverford.edu


-------  Relevant sections of http://www.cygnus.com/misc/wp/draft/ -------

  13.3.3.1.4  Reference binding                           [over.ics.ref]

1 The operation of binding a reference is not a conversion, but for  the
  purposes of overload resolution it is considered to be part of a stan-
  dard conversion sequence (specifically, it is the last step in such  a
  sequence).

2 A standard conversion sequence cannot be formed if it requires binding
  a reference to non-const to an rvalue (except when binding an implicit
  object   parameter;   see   the   special   rules  for  that  case  in
  _over.match.funcs_).  [Note: this means, for example, that a candidate
  function  cannot  be a viable function if it has a non-const reference
  parameter (other than the implicit object parameter)  and  the  corre-
  sponding argument is a temporary or would require one to be created to
  initialize the reference (see _dcl.init.ref_).  ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/03/29
Raw View
In article <DAVEW.96Mar27195129@trigati.cs.haverford.edu>
davew@trigati.cs.haverford.edu (David G. Wonnacott) writes:

|> I am looking for an explanation for the rationale behind the decision
|> of the standards committee to disallow the binding of a non-const
|> reference to an rvalue.  I assume this has been discussed to death
|> here before, but I haven't been able to find it in a FAQ; I'd be happy
|> with a reference to another document rather than a full reply here.

First: it wasn't the committee's decision (except in so far as they
didn't change the base document).  This was illegal in the ARM.

Consider the following:

    void
    incr( int& i )
    {
        i ++ ;
    }

    unsigned        j = 1 ;
    incr( j ) ;

Without the rule, the above is perfectly legal code.  However, the call
to `incr' does *NOT* modify `j', as the programmer probably expected it
would.  The reason is that incr takes an int, not an unsigned.  The
compiler implicitly converts, but the result of this conversion is not
an lvalue, but a temporary, and it is the temporary that gets bound to
the reference parameter.

I don't know when this rule was introduced, but it has been present in
all C++ texts I've seen except the first edition of Stroustrup (1986).
(Note that the exact example above appears on page 86 of _The Design_
_and_Evolution_of_C++.  Given that this was originally allowed, and that
actual practical experience found it to be a mistake, it was hardly
likely that the committee would undo it.)

There have been suggestions that only implicit conversions should be
banned, and not all rvalues.  However, as far as I know, no one ever
came up with a concrete proposal along these lines, and I believe that
the standard is too far advanced now to make the change (although it
sure would simplify the problems with auto_ptr:-).

|> The only answer I've seen for this question before is that it is
|> disallowed because the reference may outlive the rvalue it refers to.

If you want to know why certain features are (or are not) in C++, you
should definitly read the above mentioned book.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: davew@trigati.cs.haverford.edu (David G. Wonnacott)
Date: 1996/03/30
Raw View
In article <KANZE.96Mar29121910@gabi.gabi-soft.fr> kanze@gabi-soft.fr (J. Kanze
) writes:

   From: kanze@gabi-soft.fr (J. Kanze)
   Newsgroups: comp.std.c++
   Date: 29 Mar 1996 16:09:56 GMT

   First: it wasn't the committee's decision (except in so far as they
   didn't change the base document).  This was illegal in the ARM.

I shouldn't have suggested the committee invented it.

The example you cite from p. 86 of the "Design & Evolution of C++"
does show a case in which the programmer doesn't get what they wanted.
I guess I'm just complaining because I'm used to the old approach of
"If it might be useful but is usually a mistake, make it a warning,
not an error".  (For example, the ever popular "if (a = 5) ...").

The way the standard is written, I fear that this will become an
error, rather than a warning, in the near future.  My impression is
that most compiler writers use the interpretation "if the standard
says its illegal, make it an error."  I guess I'll go focus my
attention on the folks who are working on g++, in hope of ensuring
that at least g++ will continue to compile our code...

Dave W
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]