Is there something special required to use Appender.clear

Steven Schveighoffer schveiguy at gmail.com
Mon Jan 28 15:16:54 UTC 2019


On 1/28/19 7:39 AM, FeepingCreature wrote:
> On Friday, 25 January 2019 at 14:33:16 UTC, Steven Schveighoffer wrote:
>> On 1/25/19 3:20 AM, FeepingCreature wrote:
>>> On Thursday, 24 January 2019 at 17:49:34 UTC, Ali Çehreli wrote:
>>> Aren't the semantics of .clear that it's invalid to access references 
>>> to .data after calling .clear, period? And if not, then shouldn't 
>>> they be? Consider if Appender managed its own memory and held on to 
>>> previously-allocated arrays while you were appending, only to free 
>>> them on .clear. That seems like something Appender should be allowed 
>>> to do. If you don't want it, just reinitialize Appender instead of 
>>> calling .clear.
>>
>> You are advised not to. But it's not unsafe, as the memory is still 
>> there.
>>
> 
> That's stupid. Why would you advise me not to, if there's no problem 
> with it? Either it should be accepted or it should be forbidden, just 
> like warnings.

Just like this:

int[] arr = [1,2,3,4,5];
auto slice = arr[0 .. 2];
slice.assumeSafeAppend;

Now, you can use arr still, it's got elements in it beyond what slice 
has. You might have things change underneath you without expecting it. 
That's why it's advised not to do that.

But if arr is immutable(int)[], then you are running into undefined 
behavior, it's a completely different problem.

>> Without good reasons to change, I don't see why it would be accepted.
>>
>> Maybe you can describe your use case?
>>
> 
> My use case is simply the standard usecase of Appender: I want to build 
> up an array in a way that reduces GC churn. Maybe it's an array of 
> structs that contain const members that I'll serialize to JSON and send 
> on a socket. In that case, I know for a fact that no references will 
> hang around past the serialization. That's what clear _is for._ I don't 
> see why this would be different with const or immutable data; if you 
> hold references past .clear being called you're in trouble *anyways.*

Right, this does seem like a big limitation. Keeping with the spirit of 
how slices don't own the memory in question, Appender is being 
conservative with what it doesn't know.

I wonder if it may be more appropriate to instead of preventing clear() 
on immutable/const arrays, to make it @system. Or maybe call it 
something different "dangerousClear" or something ;)

There definitely should be some way to fail if clear is called on an 
array that was passed into the constructor.

But I'm still not sure we should allow overwriting immutable memory 
without a cast, even in @system code.

> I consider initializing Appender with an array referencing immutable 
> data a borderline error anyways. The entire point of Appender is that it 
> caches capacity data of GC managed memory, which is never immutable. On 
> the first append to an immutable-memory array, it has to reallocate 
> *anyways*. There is no benefit to initializing an Appender with 
> immutable memory over just appending it first thing, unless you never 
> plan to append to it ever.

It will inspect the allocated length from the GC if the array is 
appendable from the beginning. So it's not always going to reallocate.

e.g.:

string x = "abc".idup;

auto app = x.appender;

app ~= "xyz"; // does not reallocate.

-Steve


More information about the Digitalmars-d-learn mailing list