Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-11 11:51:05

"Peter Dimov" <pdimov_at_[hidden]> writes:

> David Abrahams wrote:
>> OK, so 8.5.3/5 says:
>> 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.*
>> [Footnote: Clearly, if the reference initialization being processed
>> is one for the first argument of a copy constructor call, an
>> implementation must eventually choose the first alternative (binding
>> without copying) to avoid infinite recursion. --- end foonote]
>> The constructor that would be used to make the copy shall be
>> callable whether or not the copy is actually done.
>> The problem here is, IIUC, that the implementors read that as saying
>> that, because "a constructor is called to copy..." that the
>> constructor used must be a copy constructor?
>> I don't understand why the converting constructor fails to be
>> considered when the templated SFINAE'd constructor *will* be used to
>> copy const lvalues. Templated constructors are never "copy ctors"
>> either, IIUC.
> It's a fine specimen of circular logic.
> The compiler is allowed to elide a temporary created by a copy
> constructor.
> The compiler is _not_ allowed to elide a temporary created by some
> other constructor, because this changes observable behavior and is
> not explicitly allowed.

I think what's explicitly allowed depends on your reading of 8.5.3/5

> The only copy constructor that can create a const temporary from an
> rvalue is X::X(X const &) (default arguments and ellipsis aside.)
> Therefore, once the compiler has decided to elide the temporary, it
> only needs to check for X(X const &). If such a constructor does not
> exist or is inaccessible, the elision of the temporary is illegal.

Well, I understand that as a philosophy, but I don't see it in the
standard. I also don't see any circle ;-)

> This behavior is perfectly safe and reasonable, _provided that_ the
> auto_ptr loophole does not exist. It was never intended to
> exist. Everything that is based on it goes against the core logic of
> the language.
> Does it make sense?

I guess so. I still don't know what the loophole is. I knew once,
but that knowledge is ghostly and flits away quickly.

> Once we are on the topic. As I understand it, 8.5.3 is intended to
> allow compilers to place ROM-able temporaries in ROM. Consider:
> void f(int const & x);
> int main()
> {
> f(5);
> }
> The compiler can place a temporary of type "int const" and value 5 in ROM,
> and pass its address to f. Similarly, in:
> struct X
> {
> int i;
> X(int i): i(i) {}
> };
> void f(X const & x);
> int main()
> {
> f( X(5) );
> }
> the compiler is allowed to construct a "X const" with a value of X(5) at
> compile time and place it in ROM.

OK. Relevance?

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at