[Issue 9456] New: decodeFront erroneously alters its input range with reference type ranges

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Feb 5 17:05:13 PST 2013


http://d.puremagic.com/issues/show_bug.cgi?id=9456

           Summary: decodeFront erroneously alters its input range with
                    reference type ranges
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: jmdavisProg at gmx.com


--- Comment #0 from Jonathan M Davis <jmdavisProg at gmx.com> 2013-02-05 17:05:12 PST ---
This code

import std.array;
import std.conv;
import std.utf;

class RefRange(C)
{
    @property bool empty() { return _str.empty; }
    @property C front() { return _str[0]; }
    void popFront() { _str = _str[1 .. $]; }
    @property C back() { return _str[$ - 1]; }
    void popBack() { _str = _str[0 .. $ - 1]; }
    @property auto save() { return new RefRange(_str); }
    @property size_t length() { return _str.length; }

    this(inout(C)[] str)
    {
        _str = to!(C[])(str);
    }

    C[] _str;
}

void main()
{
    auto asciiStr = "hello world";
    auto asciiRange = new RefRange!char(asciiStr);
    //auto asii = asciiStr;
    size_t index = 1;
    assert(asciiRange.decodeFront(index) == 'h');
    assert(asciiRange.length == asciiStr.length);

    auto uniStr = "プログラミング";
    auto uniRange = new RefRange!char(uniStr);
    //auto uniRange = uniStr;
    index = 3;
    assert(uniRange.decodeFront(index) == 'プ');
    assert(uniRange.length == uniStr.length);
}

gives this error when it runs

core.exception.AssertError at q(37): Assertion failure
----------------
./q(_d_assertm+0x26) [0x42c946]
./q() [0x42ac22]
./q(_Dmain+0xfa) [0x42a3da]
./q(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).void runMain()+0x18) [0x42d0dc]
./q(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x42cc1a]
./q(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).void runAll()+0x3b) [0x42d123]
./q(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x42cc1a]
./q(_d_run_main+0x1a8) [0x42cbd4]
./q(main+0x17) [0x42ca27]
/usr/lib/libc.so.6(__libc_start_main+0xf5) [0x7f60c980aa15]
----------------

The last assertion fails. If you swap which lines are commented out so that
strings are used instead of RefRange, then the code succeeds. The problem is
that decodeFront calls popFront when dealing with unicode, and it doesn't save,
so depending on what's passed to it, it may or may not pop elements. It's more
efficient to save internally in the cases where it needs to rather than ask the
caller to do so, so the correct fix is to make it save if it's going to pop
anything.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list