DIP77 - Fix unsafe RC pass by 'ref'
Michel Fortin via Digitalmars-d
digitalmars-d at puremagic.com
Fri Apr 10 04:49:01 PDT 2015
On 2015-04-09 18:43:25 +0000, Walter Bright <newshound2 at digitalmars.com> said:
> The only real purpose to a postblit is to support ref counting. Why
> would a by-value container use a postblit and not ref count?
Because reference counting has tradoffs, or because someone translates
an exiting C++ program and want to keep the semantics the same to make
the translation simpler. If you want to limit postblit to the reference
counting use case I guess that's fine, although this limitation should
probably be clarified somewhere because to someone with a C++
background it looks a lot like a substitute for a copy-constructor.
But this goes beyond containers. Destructors and postblits are
implicitly created whenever a field contained within a struct has them.
So you could have this:
struct Big
{
RCArray!T array;
int[1000] ints;
}
and now implicit copies of Big are made because Big implicitly gained a
destructor and postblit from its array field. But at least you gain
memory safety.
...or maybe not. Let's add another field to Big:
struct Handle
{
// shouldn't be able to make copies of this
@disable this(this) {}
}
struct Big
{
RCArray!T array;
int[1000] ints;
Handle handle;
}
Now Big's implicit postblit becomes disabled too (because Handle can't
handle copying), therefore it is no longer a RCO object and the
compiler will no longer create temporary copies. Now you've trashed
memory-safety.
To be fair, my opPin idea suffers a similar fate here: there is no
opPin defined for Big, which creates a hole in memory-safety. To
compensate, the compiler would have to call opPin individually for each
field that defines it.
--
Michel Fortin
michel.fortin at michelf.ca
http://michelf.ca
More information about the Digitalmars-d
mailing list