[Issue 3821] writeln doesn't detect recursive data structures yet

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Dec 29 13:23:44 UTC 2019


https://issues.dlang.org/show_bug.cgi?id=3821

Steven Schveighoffer <schveiguy at yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
                 CC|                            |schveiguy at yahoo.com
         Resolution|---                         |WONTFIX

--- Comment #9 from Steven Schveighoffer <schveiguy at yahoo.com> ---
This is generalized detection of infinite recursion. In order for format to
detect this, it would have to instrument the entire set of objects being
printed, and that is a lot of overhead for detecting something that already
throws a major error (Stack overflow). Not only that, but it depends on it
being recursive on format, and not some other mechanism to display items.

Note that a better "solution" is to update everything to calling the delegate
version of toString, which should actually output something (in the case of
writeln), before segfaulting. This gives you a hint of your error.

i.e.:

struct List1
{
    int x;
    List1 *next;
    void toString(void delegate(const(char)[]) dg) const
    {
        import std.format;
        formattedWrite(dg, "%s ->", x);
        if(next is null)
            dg("null");
        else
            next.toString(dg);
    }
}

struct List2
{
    int x;
    List2 *next;
    string toString() const
    {
        import std.conv;
        string result = x.to!string;
        if(next is null)
            return result ~ " -> null";
        else
            return result ~ " -> " ~ next.toString;
    }
}

List1 when self-referencing will print e.g. 5 -> 5 -> 5 ... forever until it
segfaults. List2 just segfaults because it never finishes building the string.

Note how in List2 I show that this does not recurse on format at all, so such a
case still wouldn't be detectable -- all the recursion is in toString.

(In reply to berni44 from comment #7)
> Meanwhile I get a segmentation fault. Doesn't make it better though...

This is a stack overflow. Segfault happens in the case of stack overflow on
many platforms.

(In reply to bearophile_hugs from comment #0)
> In Python the print is able to detect loops:

Python is a managed language, and has the possibility of doing whatever it
wants to the data types (i.e. it might be able to reserve a bit of data on each
object for this purpose), D cannot do this.

--


More information about the Digitalmars-d-bugs mailing list