lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Why does this crash?


From: Vaclav Slavik
Subject: Re: [lmi] Why does this crash?
Date: Sat, 17 Apr 2010 17:46:58 +0200

On Sat, 2010-04-17 at 16:43 +0200, Vadim Zeitlin wrote:
>  The principle applies only when you assign the value returned by the
> function to a (const) reference. It doesn't apply if you use it in any
> other way. 

Moreover, xmlwrapp is weird. It attempts to expose std iterators-like
interface in xml::node::iterator, but the internals of xmlwrapp
implementation make it impossible, so if you rely on exactly std
behavior, you may encounter weird and totally unexpected failures.

In particular: iterators' operator* returns a (const) xml::node&
reference. But internally, iterators don't iterate over xml::node, but
over libxml2's xmlNotePtrs. So when you call operator*, it creates a
"fake" xml::node corresponding to current position. This has two
consequences:

 1. Equal iterators return different references:

            xml::node root("root");
            root.push_back(xml::node("child"));
            xml::node::const_iterator a = root.find("child");
            xml::node::const_iterator b = root.find("child");
            const xml::node& na = *a;
            const xml::node& nb = *b;
            BOOST_CHECK( a == b ); // ok
            BOOST_CHECK_EQUAL( &na, &nb ); // fails!
        
 2. Iterator instance always returns the same reference, so you can't
    remember it and change the iterator:

            xml::node root("root");
            root.push_back(xml::node("one"));
            root.push_back(xml::node("two"));
            xml::node::const_iterator i = root.begin();
            const xml::node& one = *i;
            BOOST_CHECK_EQUAL( one.get_name(), "one" );
            ++i;
            const xml::node& two = *i;
            BOOST_CHECK_EQUAL( two.get_name(), "two" );
            BOOST_CHECK_EQUAL( one.get_name(), "one" ); // fails!
        

The second problem could be fixed by returning a value -- in light of
the principle you brought up, this should be backward compatible and not
result in any problems (or am I missing something?). Number one is a
harder problem and fixing it would cost some extra memory. I wonder if
any of these is worth fixing.

Vaclav
        





reply via email to

[Prev in Thread] Current Thread [Next in Thread]