DIP 1028---Make @safe the Default---Community Review Round 1

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Jan 3 22:47:05 UTC 2020


On Fri, Jan 03, 2020 at 10:23:41PM +0000, Guillaume Piolat via Digitalmars-d wrote:
> On Friday, 3 January 2020 at 22:13:28 UTC, Steven Schveighoffer wrote:
> > 
> > I'd probably have to adjust a few things, and then it will build.
> > The benefit is huge, because then someone doesn't have to choose
> > between memory safety and iopipe speed. If the compiler complained
> > about this when I was developing it, I'd fix the problems as they
> > happened.
> > 
> 
> Can anyone produce ONE example of a memory corruption code they write
> that was found with use of marking something @safe?

Ran into this a long time ago:

	struct ResourceA { /* ... */ }
	struct ResourceB { /* ... */ }
	// ...

	ResourceA getResourceA() @safe { return ResourceA(); }
	ResourceB getResourceB() @safe { return ResourceB(); }
	void freeResourceA(ResourceA*) @safe { /* ... */ }
	void freeResourceB(ResourceB*) @safe { /* ... */ }

	struct Container {
		ResourceA resA;
		ResourceB resB;
		// ...

		void delegate()[] dtors;

		this(int blah) /*@safe*/ {
			resA = getResourceA();
			dtors ~= { freeResourceA(&resA); };

			resB = getResourceB();
			dtors ~= { freeResourceA(&resA); };

			// ...
		}
		~this() {
			// Cleanup resources
			foreach (dtor; dtors)
				dtor();
		}
	}

The idea is that each allocated resource must be cleaned up when the
container goes out of scope. To prevent cleanup code from going out of
sync with allocation code, it's appended to a list of dtors immediately
after allocation (sorta like a manual version of scope(exit) that works
over an object's lifetime).

Exercise for the reader: spot the bug.

So, with @safe commented out in Container.this() as shown above, this
compiles fine with 'dmd -dip1000', even though DIP1000 ostensibly is
supposed to prevent precisely this sort of memory corruption.

Uncomment the @safe, and recompile, the compiler identifies the problem:

	test.d(17): Error: reference to local this assigned to non-scope this.dtors in @safe code
	test.d(20): Error: reference to local this assigned to non-scope this.dtors in @safe code

The reason is that DIP1000 only performs these checks in @safe code (and
for good reasons -- in @system code presumably you know what you're
doing, and should be able to do apparently unsafe things, the assumption
being that you've taken measures to prevent problems that the compiler
cannot mechanically verify).


T

-- 
What's a "hot crossed bun"? An angry rabbit.


More information about the Digitalmars-d mailing list