Topic: Binding to references [Was: Passing the result of an explicitly called constructor]


Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/12/14
Raw View
John Potter <jpotter@falcon.lhup.edu> wrote:

> On 11 Dec 99 16:20:22 GMT, Valentin Bonnard <Bonnard.V@wanadoo.fr>
> wrote:
>=20
> : Tom Payne wrote:

[Binding a D rvalue to a reference to const B; D being publically
derived from B]

> : > Does the entire D rvalue get copied, or does it
> : > get sliced down to a B rvalue?
> :=20
> : Nothing is copied. There might not exist any accessible=20
> : copy constructor anyway.

Ms. Bonnard failed to notice that 8.5.3/5 states that:
"The constructor that would be used to make the copy shall be callable
whether or not the copy is actually done."

That constructor needn't be a copy constructor though (see
std::auto_ptr).

> Interesting point.  I have an implementation which seems to copy
> builtins but not UDTs. =20

The part of 8.5.3/5 allowing the choice applies only to class types
(where no conversion other than derived-to-base and possibly a
qualification conversion is involved).
In other cases (among them built-ins) a copy is required using
copy-initialization semantics. That copy will have the type of the
reference.

That rule disallows getting the address of a literal:

    void foo(const int& r) { std::cout << &r; }
   =20
    foo(2); // wont yield the address of the literal 2 ;)

OTOH copies of temporaries might be elided as usual.

>In the example above, a reference of type
> B const is bound to an rvalue of type D.  The implementation has
> a choice of binding it to the B part of that D or of creating a
> temporary of type D const and binding to the B part of that.
>=20
> If there is no accessible copy ctor, the program is well formed
> in the first case and ill formed in the second case.

It is ill-formed in either case.

> If f contains
>    B& rp(const_cast<B&>(parm));
> the program is well behaved in the first case and has undefined
> behavior in the second case.

This is an interesting point. In a recent discussion someone proposed:

    template <class T>=20
    T& lvalue(T const& rvalue)
    { return const_cast<T&>(rvalue); }
// May be the original was a specialization of this

to allow something like:

    lvalue( ifstream("Hello.txt") ) << "Hello World";

and similar uses for rvalues returned from functions.

It now seems that this proposal may lead to undefined behaviour (and the
example is ill-formed, as the copy c'tor for ifstream is missing).

> Is it really intended that an implementation decision can make
> these changes in the validity of a program?

The implementation decision does not make an ill-formed program
well-formed (your first concern). The other problem just shows how
dangerous const_cast is and invalidates its use in one more context.
OTOH I'd be surprised to see a case where the undefined behaviour caused
by the copy actually did behave differently. I dont expect
implementations to create temporaries of const type in read-only memory.
=20
> John

I also have a question of my own. Having:

    struct B {=20
        B();=20
        B(B volatile const&);=20
        virtual char const* name() const volatile { return "B"}
    };

    struct D {=20
        D();=20
        D(D volatile const&); };
        virtual char const* name() const volatile { return "B"}
    };

    extern D foo();
    extern D volatile bar();

    void baz(B const& b) { std::cout << b.name() << std::endl; }

    int main() {
        baz( foo() );
        baz( bar() );
    }

It seems as though the output must be:
    D
    B
Am I right ? Is it legal at all ?

Also, if baz were changed to have signature=20
    void baz(B volatile const&)=20
it seems that both calls to baz would be ill-formed.

How does this related to the signature of the copy constructors ? Can a
volatile rvalue be copied at all ?

-- J=F6rg Barfurth
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]