This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/29437] New: [decl.init.ref]/5 wrongly implemented


[decl.init.ref]/5 has the following text for initialization of
constant references with rvalues:

5 A  reference  to type "cv1 T1" is initialized by an expression of type
  "cv2 T2" as follows:
[...]
      --  If  the  initializer  expression is an rvalue, with T2 a class
          type, and "cv1 T1" is reference-compatible with "cv2 T2,"  the
          reference is bound in one of the following ways (the choice is
          implementation-defined):

          --  The reference is bound to the object  represented  by  the
              rvalue  (see  _basic.lval_) or to a sub-object within that
              object.

          --  A temporary of type  "cv1 T2"  [sic]  is  created,  and  a
              constructor  is  called  to  copy the entire rvalue object
              into  the  temporary.   The  reference  is  bound  to  the
              temporary or to a sub-object within the temporary.93)

          The constructor that would be used to make the copy  shall  be
          callable whether or not the copy is actually done.  [Example:

             struct A { };
             struct B : public A { } b;
             extern B f();
             const A& rca = f();             // Either bound to the A
sub-object of the B rvalue,
                                             //   or the entire B object is
copied and the reference
                                             //   is bound to the A sub-object
of the copy

           --end example]


gcc apparently implements the second alternative, i.e. it copies objects.
However, it only copies the base object, i.e. it creates a temporary of
type "cv1 T1", where the standard requires "cv1 T2" (not the [sic] in the
wording.

Testcase:
-----------------
#include <iostream>

struct Base{
    Base() { std::cout << "Base ctor\n";  }
    Base(const Base &) { std::cout << "Base copy ctor\n";  }
    ~Base() { std::cout << "~Base called\n"; }
};

struct Derived: public Base{
    Derived() { std::cout << "Derived ctor\n"; }
    ~Derived() { std::cout << "~Derived called\n"; }
    Derived(const Derived &) { std::cout << "Base copy ctor\n";  }
};

int main ()
{
  bool b = false;
  const Base& ref = b ? Base() : Derived();
}
----------------------------

g/x> /home/bangerth/bin/gcc-4.2-pre/bin/c++ x.cc
g/x> ./a.out 
Base ctor
Derived ctor
Base copy ctor
~Derived called
~Base called
~Base called

As can be seen, only Base is copied, when we are required to copy Derived.

W.


-- 
           Summary: [decl.init.ref]/5 wrongly implemented
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bangerth at dealii dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29437


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]