Thread: Difference in STL implementations...

  1. #1
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391

    Difference in STL implementations...

    At school here compiling with dev-cpp I'm getting strange results in my program.

    I'm using STL <list>. Now at home using g++ 4.2.3 (or whatever the latest version is) it seems it treats the end of the list differently, than it's being treated using dev-cpp (don't know which version of g++ or mingw it is).

    Well quite frankly, it is treating it differently. As my main program loop get's back to the end of the list it treats:

    it = mlist.end();

    as if it were:

    it = mlist.begin();

    I know it's doing this, because my code has worked w/out problem with the latest version of g++.

    But here at school, the compiler acts like it doesn't understand.

    What's the deal?

    Was <list> not treated as a circular list in older versions?
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Er, what?

    Bugs in the implementation aside, the observable behaviour of the STL is clearly defined by the standard, with no leeway. A list is not circular. You simply have a bug, and for whatever reason, it didn't show up until now. But it's definitely a bug. And I have no idea how it could ever work for you.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Are you perhaps using forward and reverse iterators? Maybe the bug is somewhere in there... It has to be a bug.
    It would be interesting to see some relevant parts of the code.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    not the answer I was hoping for anyway... d*mn it!

    I've spent the last hour trying to trace the problem, and I know where the problem is, but the crazy thing is that I hadn't changed a thing between compiling it on my laptop, and then here at school.

    Ok, imagine you have points at the three points of a triangle. If the points are in a <list>, then one of those points is the begin(), one is in the middle, and the last one is at end().

    Now, if I make insertions between each of those points, begin and end() don't change.

    The last segment ( the one between end() and begin() ) is where the problem lies. At home, I had no problems with:
    Code:
    list<blah>::iterator it myfunc(list<blah>::mlist&, list<blah>::iterator it){
    
        some_value = it->get_a_value();
    
        ++it;
    
        some_other_value = it->get_a_value();
    
        // Do stuff...
    
        return it;
    }
    but now everything is all jacked, and I'm dismayed., It would be easy enough to fix with some conditional tests, but why the frick won't it work? I understand that:
    Code:
    ++it;
    maybe referencing something weird if it enters the func() @ mlist.end(), but it worked before.

    I don't get it...
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Ok, imagine you have points at the three points of a triangle. If the points are in a <list>, then one of those points is the begin(), one is in the middle, and the last one is at end().
    That is not true. One is at begin(), one is at advance(begin(), 1), the last one is at advance(begin(), 2). end() returns an iterator one past the last element in the container.

    EDIT:
    oh wait, I am using the advance(begin(), n) thing rather loosely since advance() advances the iterator passed to it. It does not return an iterator. But hopefully you get the idea.
    Last edited by laserlight; 02-05-2008 at 12:33 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    well, you know you have a bug in there. That's half a step. The second half is fixing it.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    i guess i won't be able to compare until i get back to my laptop... i'll repost if I'm still having issues.

    Thank you all anyway.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    After going ++it, you're not allowed to dereference it unless you have determined that it is not equal to end(). You should check that.
    For that matter you should also be careful to ensure that when you dereference it before the ++it, that it was not already equal to end().

    Is this for a triangle clipper in a software 3D engine? I would suggest using a vector of vertex indexes instead of a list, if it is.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    [qoute]Is this for a triangle clipper in a software 3D engine? I would suggest using a vector of vertex indexes instead of a list, if it is.[/quote]

    No. We're making ->these<-.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  10. #10
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    All right, I fixed this nonsensical madness for now. It will be interesting however to see what the heck the difference was...

    here's the fix (using the above posted code snippet):
    Code:
    list<blah>::iterator it myfunc(list<blah>::mlist&, list<blah>::iterator it){
    
        some_value = it->get_a_value();
    
        ++it;
    	
        /*  I need these values, but it all depends on where I am in the list...
        */
        double second_x;
        double second_y;
    
        if(it == l.end()){
            
                list<Coord>::iterator it2 = l.begin();
                second_x = it2->get_x();
    	    second_y = it2->get_y();
        }
        
        else{
            
                second_x = it->get_x();
    	    second_y = it->get_y();
        }
    
        // Do stuff...
    
        return it;
    }
    I guess the lesson I learned here is that my program didn't care where end() was but rather that it got there at all...
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  11. #11
    The larch
    Join Date
    May 2006
    Posts
    3,573
    So you want to jump back to the beginning of the list when you reach end?

    Without code reduplication you could use
    Code:
        if (it == l.end()) it = l.begin();
    And carry on as normal.

    The difference is that the iterator returned by end shouldn't be used for anything else than testing if you have reached the end of the container. You shouldn't dereference it and you shouldn't try to increment it.

    Your function would work now as long as you don't pass it an end() iterator initially.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Do you really think it's wise for a function to increment the iterator like that? Normally you would call this function from inside of a loop that owned the iterator and simply passed it to this function. That way you would have the correct iterator upon entry to the function. And you can guarantee that if you have an iterator related bug you know it's in the function that contains the loop code, not in this function. Iterating like this could introduce several problems into your code.

    I normally try to increment iterators in exactly one place so that they are not getting incremented and altered all over my code.

    Code:
    while (iter != m_mylist.end())
    {
       SomeFunc(iter);
       ++iter;
    }
    SomeFunc here would not alter the iterator which delegates this responsiblity back to the code that really should increment the iterator. You currently have this:

    Code:
    while (iter != m_mylist.end())
    {
      iter = SomeFunc(iter);
    }
    It is not apparent here that the iterator is getting incremented. It's not hard to deduce, but who knows what SomeFunc() is doing with the iterator? The logic for incrementing is hidden inside of SomeFunc(). You could really run into trouble if SomeFunc() erased something from the list.
    Last edited by VirtualAce; 02-05-2008 at 06:02 PM.

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    What exactly does myfunc() do? (and I hope that's not the real name since it tells you nothing about what it does).
    Maybe there's an easier & safer way to do what you want using some STL algorithms?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C Formatting Using STL
    By ChadJohnson in forum C++ Programming
    Replies: 4
    Last Post: 11-18-2004, 05:52 PM
  2. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  3. STL or no STL
    By codec in forum C++ Programming
    Replies: 7
    Last Post: 04-12-2004, 02:36 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM