On 2010-09-19 19:09:36 -0400, Fabrizio J Bonsignore said:
No, there is no assignment. x is constructed with AO's copy constructor.
Which explicitly ought to read AO x( Function() ); and obviate the
operator = syntax, because such syntax seems to imply rather:
AO &x = *&Function();
or, take the address of the temporary, dereference it and reassign it
as a reference. The temporary was just moved from one implicit alias
to an explicit alias and memory is reused, plus saving a function
call. Anyway both objects are assumed to be built in a frame! And all
these operators are tautological but avoid a copy constructor call.
Not supposedly, that's how it's defined. It's not an optimization.
I am used to think of AO x = Function(); as invoking a useful copy
constructor, but now such copy constructor looks ambiguous! Then AO
x( Function() ); is equivalent to:
AO *pFunction() {... return new AO;}
AO &AO:
perator=(AO &x) {if (this==&x) return x; ...}
AO *xp = pFunction(); //save the returned address, like a stack frame
AO &x = xp->operator=( *xp );//assign! instead of calling copy
constructor
or, get the address of the returned object, invoke operator= on it
with itself as argument (!) and assign the result to a reference to
object with the final by-value alias. This IS an assignment
construction, but not a copy (memory) construction, and it is optimum
since we avoid wasting an instance of the relevant object. The copy
constructor, implicit or explicit, here, is wasteful!
So unless the invoked copy constructor does anything beyond bitwise
copy, the call to the constructor is only necessary to move the same
data from one stack frame to another frame? Or to move an address
value and then copy the same data into another heap area with another
address value? This is much clearer using a pointer directly:
AO Function() {
AO *p = new AO; //assign and initialize in the heap
AO &w = *p; //get a by value working reference
.... //do some work on w
return w; //w returns a handle to the memory in p
}
AO &x = *&Function(); //x should point now to the content of *p!
or
AO *pFunction() {... return new AO;}
AO &x = *pFunction(); //&(x) != pFunction() but &x == pFunction() !!
and neither copy nor assignment constructor are called but the
relevant object is still referred to in the program and the assignment
was optimized, though we have to remember to delete &x; later because
it was built in the heap in Function(). A copy constructor here seems
like a way to manage memory so this final delete is not forgotten by
the system nor the user s responsibility...
If we have instead:
AO x; //build a new AO
.... //do process on x
AO z( x ); //copy constructor to get a new copy of x
.... //do process on x and z
x = z; //discard x, call assignment operator...
then both copy constructor and assignment operator= are justified,
distinct and necessary and syntax and semantic match intuitively. We
need two memory areas for AO data. So the choice is between AO z( x );
and AO z = x; !!! Seems just an idiomatic preference, but now it does
not seem to be the same at all if the asignee comes from a function
call returned by value. Then return by value should be avoided for
efficiency and the copy constructor called explicitly always, or
always use pointers as return values and avoid using automatic
objects... which seems to be a bad contract with the language if you
have to avoid a valid construction when it is just a matter of
guaranteeing some efficiency.
I do not think it is very correct if I have to download the _source_
to the compiler, review it, modify it and bootstrap it (if at all
possible with my working version...), because the application is not
implementing well its specification! And then I find basic doubts
about the efficiency of its constructions violating the principle of
explicit semantic, which seems to have confused implementors.
In my simple test case:
*omitting both definitions compiles without trouble
*omitting the copy constructor and const fails the statements:
AO f;
f = Retit(); //no match for 'operator=' in 'f = BO::Retit()()'
f = Retut(); //idem
but accepts
AO m = Retit(); //omitted copy constructor
*omitting the copy constructor and adding const to the assignment
operator= passes.
*omitting the assignment operator= and adding const to the copy
constructor passes.
*omitting the assignment operator= and const fails statements:
AO m = Retit(); //no matching function for call to `AO::AO(AO)'
AO o( Retit() ); //returns a class member
AO f;
f = Retit();
but accepts
AO g = Retut();//!!! returns a temporary built in the stack
*defining both assignment operator= and copy constructor with
signatures
AO &operator=(AO &x);
AO(const AO &x);
fails
f = Retit(); // no match for 'operator=' in 'f = BO::Retit()()'
f = Retut(); // returns member variable
*defining both assignment operator= and copy constructors with
signatures
AO &operator=(const AO &x);
AO(AO &x);
fails to compile
AO m = Retit();
AO o(Retit());
AO g = Retut();
AO h(Retut());
f = Retit();
f = Retut();
but accepts
AO b;
b = BO::a;//assign from member
AO c(a);// should fail too...
AO j = g;
So far in the real code that exposed the bug adding const to the copy
constructor alone compiles, though an unexpected error remains that
crashes the runtime library at exit, beyond reach of the debugger,
because seemingly one destructor fails to be called. Then adding const
to the assigment operator= definition begins complaining about
'discarding qualifiers' inside the operator= definition, in a method
returning a logical bool... I do not want to think templates are
affecting the issue because this three classes system is typical and
autonomous... but it still feels like some internal tree got
twisted...
Danilo J Bonsignore
================================================================================================
F Emporium B, trouble with an employee not wanting to give me Jihad
coffee (Illy, as another employee called it) but ... coffee, which
another employee distinguishes as decaf (normal tasting) from just
coffee ($%@# tasting), then going into a string of complaints and
blaming to names I have never heard.