This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/29437] New: [decl.init.ref]/5 wrongly implemented
- From: "bangerth at dealii dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 12 Oct 2006 01:36:37 -0000
- Subject: [Bug c++/29437] New: [decl.init.ref]/5 wrongly implemented
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
[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