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

Reply via email to