[phobos] Bug 3763 (How to fix readlnImpl())
dsimcha at gmail.com
Wed Feb 3 17:49:21 PST 2010
I recently filed bug 3673
(http://d.puremagic.com/issues/show_bug.cgi?id=3763) and started looking
at possible fixes. This is a bug in std.stdio.readlnImpl(). However,
the more I think about it the more I think the function needs to be
completely rethought, not just patched. I'm not sure if this is a high
priority given that it has nothing to do with the language spec and TDPL
but it's a pretty embarrassing quality of implementation issue.
Anyhow, readlnImpl() takes a ref char and tries to recycle the memory
to read in another line. In doing so, it queries GC.capacity for the
relevant memory block and resizes the array to the size of the memory
block. This is arguably unsafe in the general case because, if someone
passes in a slice that starts at the beginning of a GC block to use as
the buffer, everything else in the same GC block can get overwritten.
This massively violates the principle of least surprise. On the other
hand, when encapsulated in the higher level API of byLine(), it's both
safe and efficient.
A second issue is that the GCC_IO and GENERIC_IO versions use the
buf.length = 0;
// append to buf
This, IIRC, isn't going to result in the memory block being recycled
anymore once Steve's changes to the way arrays work are checked in. The
best thing to do IMHO is to solve the general case of this problem by
adding a useExistingBuffer() function to std.array.Appender. This would
take an existing array of elements that must be mutable, set the
Appender's capacity field to the array's length (NOT its capacity as
reported by the GC, to avoid stomping on arrays that are not owned by
the current scope), and then work like it does now.
More information about the phobos