obliterate

Jonathan M Davis jmdavisProg at gmx.com
Tue Nov 12 17:36:51 PST 2013


On Tuesday, November 12, 2013 17:19:04 Andrei Alexandrescu wrote:
> On 11/12/13 4:59 PM, Jonathan M Davis wrote:
> > On Tuesday, November 12, 2013 16:33:17 Andrei Alexandrescu wrote:
> >> Hello,
> >> 
> >> 
> >> I will soon get to work on typed allocators; I figured there will be
> >> some issues percolating to untyped allocators that will require design
> >> changes (hopefully minor).
> >> 
> >> For starters, I want to define a function that "obliterates" an object,
> >> i.e. makes it almost surely unusable and not obeying its own invariants.
> >> At the same time, that state should be entirely reproducible and
> >> memory-safe.
> >> 
> >> Here's what I'm thinking. First, obliterate calls the destructor if
> >> present and then writes the fields as follows:
> >> 
> >> * unsigned integers: t.max / 2
> >> 
> >> * signed integers: t.min / 2
> >> 
> >> * characters: ?
> >> 
> >> * Pointers and class references: size_t.max - 65_535, i.e. 64K below the
> >> upper memory limit. On all systems I know it can be safely assumed that
> >> that area will cause GPF when accessed.
> >> 
> >> * Arrays: some weird length (like 17), and also starting at size_t.max
> >> minus the memory occupied by the array.
> >> 
> >> * floating point numbers: NaN, or some ridiculous value like F.max / 2?
> > 
> > 1. How is this different from destroy aside from the fact that it's
> > specifically choosing values which aren't T.init?
> > 
> > 2. What is the purpose of not choosing T.init?
> 
> Consider a memory-safe allocator (oddly enough they exist: in brief
> think non-intrusive unbounded per-type freelist). That would allow
> access after deallocation but would fail in a reproducible way.
> 
> The idea is that it should fail, so T.init is not good.

Except that pretty most of your examples don't seem like they would fail any 
more than T.init would. int.max / 2 in so no more valid or invalid than 0. The 
only difference I see would be that by setting pointers/references/arrays to a 
weird value rather than null, they'll be treated as if they have a value and 
then blow up rather than blowing up on a null value. For all the built-in 
types, T.init is essentially supposed to be as invalid as the type can get 
without pointing off into memory that it shouldn't be addressing.

So, the only thing I see that this suggestion does over using T.init is that 
on pointers/references/arrays, you won't end up with code that checks for null 
and avoids blowing up. Code that checks for null would then blow up just as 
much as code that assumes that the pointer/reference/array was non-null. But 
that's the only difference I see, since none of the other types end up with 
values that are any more invalid than T.init.

- Jonathan M Davis


More information about the Digitalmars-d mailing list