redefining "put" and "OutputRange"
monarch_dodra
monarchdodra at gmail.com
Fri Aug 30 03:53:37 PDT 2013
I'm starting this thread, first, as a shamless plug to a brand
new pull I just did, which (amongst others) allows "put" to
transcode on the fly any string/char of any length, to any
string/char of any length.
This fixes issues mostly in std.format, and also allows things
like formattedWrite to work with pure delegates (it didn't
before), as well as output directly in wstring or dstring format
(awesome for writing to a UTF-16 file, for example).
--------
The real reason I'm starting this thread is I believe the current
way "put" leads to a *MASSIVE*, *HORRIFYING* issue. I dare not
say it: Escaping references to local stack variables (!!!).
Basically, if R accepts an "E[]", than put will accept a single E
element as input, and convert it to an "E[]" on the fly, using
"put(r, (&e)[0 .. 1]);". I'm sure you can see the problem. It
allows things such as:
//----
void main()
{
Appender!(int[][]) app; //A type that accumulates slices
put(app, 1);
put(app, 2);
put(app, 3);
writeln(app.data); //prints: [[3], [3], [3]]
}
//----
Oops!
I'd like to make a proposition: "put" needs to be changed to
*not* accept putting an E into something that accepts E[]. There
is simply *no way* to do this safely, and without allocating
(both of which, IMO, are non-negotiable).
For objects that define put/opCall, then it is not very
complicated to have two different signatures for
"put(E[])"/"opCall(E[])" *and* "put(E)"/"opCall(E)". This makes
it explicit what is and isn't accepted.
Lucky enough, the problem never existed with input ranges:
"int[][]" never accepted "int", so there is no problem there.
The last thing remaining are "sinks" (delegates and functions).
As a convenience, and *only* for characters sinks, because we
*trust* them to make local copies of elements, we can allow
things like:
put((const(char)[]){}, 'a');// OK
put((const(char)[]){}, '本');// OK
put((const(char)[]){}, "hello"d);// OK
put((const(wchar)[]){}, "hello"c);// OK
This, I think, is what is safest, but still leaves a little open
door, exceptionally, for easy formatting.
--------
So, the idea is now to yay or nay my change proposal, and/or
discuss my pull:
https://github.com/D-Programming-Language/phobos/pull/1534
More information about the Digitalmars-d
mailing list