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