Can't recreate a range?

Steven Schveighoffer schveiguy at gmail.com
Thu Apr 30 16:21:05 UTC 2020


On 4/30/20 11:42 AM, Casey wrote:
> On Thursday, 30 April 2020 at 13:23:25 UTC, Paul Backus wrote:
>> Using a default value like this means that it will be shared among all 
>> instances of the struct. Instead, you should set `buff = 
>> appender!string` in the constructor, so that each struct will have its 
>> own appender.
> 
> I'll give it a try when I get back to it (fixing lint issues), but are 
> you sure that's the issue?  In popFront, I recreate the appender.  So, 
> the appender should be clear before the empty check after it processes 
> the last of the data from _input.  Still a good thing to do as a best 
> practice; I'm just wondering if something else is causing an issue and 
> even if initializing the appender in the constructor solves the problem, 
> I'd be suspect of future issues cropping up.

I would say part of the issue is that you are doing all your work in 
front and not popFront.

What happens is that Appender is a pointer-to-implementation struct, and 
the compiler will allocate the first one shared amongst all initial 
StreamRange instances.

On your first call to front, it's going to utilize that shared one. Then 
on the call to popFront, it will reset it to another one.

For the second unittest, in your first call to front, it notices that 
it's already been filled, so it doesn't do any work (and returns the 
existing buffer).

another problem, your empty condition is based on the input, which 
violates range expectations. indeed, on the first call to front, the 
range all of a sudden becomes empty.

I'd say:

1. move your work to the popFront function (you then need to call 
popFront once before returning the range in your factory method).
2. change empty to check if the buffer is empty instead of the input.

Some other observations:

3. You don't need a further Range parameter for the nested struct, it 
can use the template parameter from the containing function.
4. Make it a static struct, or else it will retain a pointer to the 
function stack frame needlessly.

-Steve


More information about the Digitalmars-d-learn mailing list