On Thursday, September 6, 2018 2:40:08 AM MDT Saurabh Das via Digitalmars-d- learn wrote: > Is this a bug with writeln? > > void main() > { > import std.stdio, std.range, std.algorithm; > > auto a1 = sort([1,3,5,4,2]); > auto a2 = sort([9,8,9]); > auto a3 = sort([5,4,5,4]); > > pragma(msg, typeof(a1)); > pragma(msg, typeof(a2)); > pragma(msg, typeof(a3)); > > auto b = [a1, a2, a3]; > pragma(msg, typeof(b)); > > writeln("b:"); > writeln(b); > writeln(b); // <-- this one prints incorrectly > > writeln("a:"); > writeln(a1); > writeln(a2); > writeln(a3); > > } > > Output > ====== > > SortedRange!(int[], "a < b") > SortedRange!(int[], "a < b") > SortedRange!(int[], "a < b") > SortedRange!(int[], "a < b")[] > b: > [[1, 2, 3, 4, 5], [8, 9, 9], [4, 4, 5, 5]] > [[], [], []] > a: > [1, 2, 3, 4, 5] > [8, 9, 9] > [4, 4, 5, 5] > > The issue goes away if I cast 'b' to const before writeln. I > think it is a bug, but maybe I am missing something?
It's not a bug in writeln. Any time that a range is copied, you must not do _anything_ else with the original unless copying it is equivalent to calling save on it, because the semantics of copying a range are unspecified. They vary wildly depending on the range type (e.g. copying a dynamic array is equivalent to calling save, but copying a class reference is not). When you pass the range to writeln, you must assumed that it may have been consumed. And since you have range of ranges, you must assume that the ranges that are contained may have been consumed. If you want to pass them to writeln and then do anything else with them, then you'll need to call save on every range involved (which is a bit of a pain with a range of ranges, but it's necessary all the same). In many cases, you can get away with passing a range to a function or use it with foreach and then continue to use it after that, but that's only because copying those ranges is equivalent to calling save on them. It doesn't work if any of the ranges involved aren't saved when they're copied, and it doesn't work in generic code, because you have no clue whether the ranges that are going to be used with that code are going to be saved when they're copied. - Jonathan M Davis