endsWith() doesn't work with const(wchar[])s

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 14 00:11:14 PST 2011


On Thursday 13 January 2011 23:21:03 %u wrote:
> > Regardless, a fully const array is never going to work with a function
> > like
> 
> endsWith() for the simple reason that such functions have to actually be
> able to process the range that they're given, and if the range is const,
> you can't call popFront() or popBack() on it, so it just isn't going to
> work.
> 
> > Now, if you take a _slice_ of a const array, it should work, because
> > while the
> 
> elements of the array will remain const, the slice itself won't be, so
> endsWith() can process it.
> 
> I see what's happening, but the problem with slicing is that it doesn't
> prevent a resize of the array, which, if not allocated with GC memory,
> could break code. How can you have a non-resizeable slice, while still
> maintaining the constness of an array? Is that even possible?

Well, if you're talking about anything in std.algorithm, it's dealing in ranges, 
not arrays, so it's not going to resize anything. In fact, very little in Phobos 
would end up resizing an array. Most stuff deals explicitly with ranges. I doubt 
that anything in std.string does either. But anything there would either create 
a straight up slice or create a new string, which would be freshly allocated by 
the GC.

And actually, even if a slice were resized, I'm not sure that it _would_ cause 
any problems. I'm not sure what would happen if it were to try and resize in 
place (it probably couldn't since, a non-GC-allocated array likely wouldn't have 
any extra capacity), but if it couldn't then it would have to allocate a new 
array, which would then be GC-allocated. The original slice would have just 
pointed to the original array, so that wouldn't cause a leak. You'd still have 
to worry about cleaning up the original array, but any new ones which were 
created would be GC-allocated and then definitely wouldn't be leaking anything.

Of course, in the general case, I wouldn't really advise manually allocating 
arrays unless you really need to. Unless profiling shows that the GC-allocated 
arrays are a bottleneck, it's just simpler and safer to allow the GC to do its 
job. The one exception to that would be if the array in question came from a C 
call or something similar where it couldn't be GC-allocated. But generally, 
range-based functions shouldn't be allocating new arrays. The closest that I can 
think of would be save() on Forward Ranges, and I believe that that's a slice 
for arrays, so nothing would be allocated.

In any case, very little range-based anything is going to be able to work on 
fully const ranges. It just isn't possible. However, very little that's range-
based would be doing any kind of reallocation of arrays - _especially_ something 
like endsWith(). I don't think that even std.string does much in the way of 
array reallocation - if any at all.

Still, if you're really trying to use arrays which aren't GC-allocated, the 
safest way would be to just use functions that you write yourself. While it's 
possible to use non-GC-allocated arrays, the language isn't particularly 
friendly towards them. They're really supposed to be allocated by the GC. Still, 
I believe that the functions in std.algorithm should work just fine without doing 
any reallocating, since they all work on ranges, not arrays.

- Jonathan M Davis


More information about the Digitalmars-d mailing list