More range woes: composed ranges are unsafe to return from functions

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Oct 16 13:54:49 PDT 2012


On Tue, Oct 16, 2012 at 12:33:20PM -0700, H. S. Teoh wrote:
[...]
> Another data point: if I move the .joiner call out of cprod() into
> main(), then there is no problem. Could it be that something in joiner
> is breaking somehow, when returned from a function?
[...]

I found a reduced case:

	import std.algorithm;
	import std.range;
	import std.stdio;

	auto boo() {
		auto C = [2];
		return
			[1,1]
			.map!((a) => C)
			.joiner
		;
	}

	void main() {
		auto C = [2];
		writeln(
			[1,1]
			.map!((a) => C)
			.joiner
		.take(12));

		writeln("====");

		writeln(boo().take(12));
	}

Excuse the odd formatting, I wanted to make sure the [1,1,1].map!(...)
parts are line-for-line identical between boo() and main().

This example segfaults in the last writeln. Commenting out .joiner makes
the segfault go away. Reducing [1,1] to a 1-element array makes the
problem go away. Replacing C with [1] makes the problem go away.
Removing map!(...) and replacing it with something involving C makes the
problem go away. Deleting the .take(12) outputs a whole mass of garbage
values and then segfaults.

So it seems like there is some kind of bad interaction between map and
joiner. Maybe as jethro said, it's wrong code produced by dmd for the
delegate passed to map? It seems to be dependent on the reference to the
local variable C, which seems to imply a corrupted (or just
out-of-scope?) delegate context.


T

-- 
The best way to destroy a cause is to defend it poorly.


More information about the Digitalmars-d mailing list