Topic: Destructive References


Author: cabo@informatik.uni-bremen.de (Carsten Bormann)
Date: 30 Oct 1994 18:51:15 GMT
Raw View
WARNING: Do not read this if you don't know what p->~T() means and
where you would use it.  It might boggle your mind.

WARNING to C++ standardizers: This is in comp.std.c++ as it presumes
knowledge of the C++ standard library as per WP 9/20/1994.
It is not a proposal to add this to the language before CD ballot.


In many cases, copy constructors and assignment operators are
relatively expensive, as they have to generate a copy of some
representation object as well as a copy of the object itself.
If the object being copied is going to be overwritten or destroyed,
anyway, this overhead is avoidable in principle.

This is the reason the C++ library defines a template called swap()
that can be specialized for types such as string that simply need to
swap their members and do not need to touch their representation
objects.

For certain applications such as the library function objmove(), it
would be beneficial to have a destructive copy constructor, i.e. one
that is tasked with destroying its argument as well as with
constructing a new object.  This provides the same economies as
swap(), but for the unidirectional case:

enum destructive_t { destructive };

string::string(string& s, destructive_t) {
 ptr = s.ptr; len = s.len; res = s.res;
}

template<class T> construct_and_destroy(void *p, T& t) {
 new(p) T(t, destructive);
}

Now, if the compiler knew about destructive arguments, it could use
destructive constructors and other destructive member functions, such as

// not legal C++
string::operator=(string& s, destructive_t) {
 if (ptr) free(ptr);
 ptr = s.ptr; len = s.len; res = s.res;
}

in cases where it would have to destroy a temporary, anyway.

Presto,

 string a, b, c;
 a = b + c;

is nearly as efficient (as measured in the number of allocations) as

 string a = b; a += c;

If you don't like adding a parameter for destructive parameter
passing, I have this alternative syntax for you (please don't bicker,
this is just one possible syntax):

// not legal C++
string::operator=(string~& s) {
 if (ptr) free(ptr);
 ptr = s.ptr; len = s.len; res = s.res;
}

What is a T~& (or a T~*)?  It is a reference (or a pointer) to an
object that carries the responsibility to destroy (not delete!) the
object.  ~ here syntactically feels like a qualifier, such as const.
There is, however, no implicit conversion from a T& to a T~& -- a T~&
is generated only in two cases:

 explicit conversion (kind of a promise for destruction)

 as an optimization by the compiler when it would have to
 destroy the object anyway.

Of course, writing a template for things like construct_and_destroy
would become simpler if the compiler would convert a T~& to a T&
implicitly as a standard conversion, noting that it has to destroy the
object at the next appropriate point.

Comments?

Gruesse, Carsten