CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Size_t Weird Bug within Loop

    Hello to all expert,

    Code:
    vector<string> obj;
    
    	obj.push_back("asdas");
    	obj.push_back("fgh");
    	obj.push_back("vb");
    	obj.push_back("fgh");
    	obj.push_back("asdas");
    	obj.push_back("ljk");
    
    	for (size_t loop = obj.size() - 1;
    			loop>=0;--loop)
    	{
    		cout << obj[loop] << "\n";
    	}
    The loop cout down from 5-4-3-2-1-0-4294967295(unsigned int loop). Then exception is thrown.

    Minimum unsigned int(size_t) is 0.

    Thanks.
    Thanks for your help.

  2. #2
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Size_t Weird Bug within Loop

    Because your decrement loop is completely wrong. Try

    Code:
    for (size_t loop = obj.size(); loop--; )
    {
     ...
    }

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by Peter_APIIT View Post
    The loop cout down from 5-4-3-2-1-0-4294967295(unsigned int loop). Then exception is thrown.
    How is this any different for any loop that uses unsigned counters?

    The solution is simple -- don't write loops this way that rely on unsigned values to be valid and not wrap around.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by Paul McKenzie
    The solution is simple -- don't write loops this way that rely on unsigned values to be valid and not wrap around.
    Yes, and an alternative would be to use reverse iterators obtained via rbegin() and rend(). In fact, in this case instead of a loop a simple application of std::copy would suffice, e.g.,
    Code:
    copy(obj.rbegin(), obj.rend(), ostream_iterator<string>(cout, "\n"));
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by PredicateNormative View Post
    Because your decrement loop is completely wrong. Try

    Code:
    for (size_t loop = obj.size(); loop--; )
    {
     ...
    }

  6. #6
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Size_t Weird Bug within Loop

    GCDEF,

    While PredicateNormative's loop is "unusual" and I would definately recommend one of the other approaches, it does apper to be valid.

    It will iterate the desired number of times, with loop containing a valid [but off by one] index. The last iteration of the loop, will cause the post decrement to leave loop in a poorly defined state (it will have wrapped), but there would be no access to the variable once it occured.

    IMHO a on the approach, but I can't go as far as saying it is "wrong" (unless of course I am missing something.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  7. #7
    Join Date
    Aug 2005
    Location
    LI, NY
    Posts
    576

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by TheCPUWizard View Post
    GCDEF,

    While PredicateNormative's loop is "unusual" and I would definately recommend one of the other approaches, it does apper to be valid.

    It will iterate the desired number of times, with loop containing a valid [but off by one] index. The last iteration of the loop, will cause the post decrement to leave loop in a poorly defined state (it will have wrapped), but there would be no access to the variable once it occured.

    IMHO a on the approach, but I can't go as far as saying it is "wrong" (unless of course I am missing something.
    Agreed that it's odd. If I must write a loop that breaks form like that, I tend to prefer writing it as a while-loop. I don't think anyone should have to take a second look at a for-loop to see what it does; they should be used for readability's sake, not for brevity.
    - Alon

  8. #8
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by TheCPUWizard View Post
    GCDEF,

    While PredicateNormative's loop is "unusual" and I would definately recommend one of the other approaches, it does apper to be valid.

    It will iterate the desired number of times, with loop containing a valid [but off by one] index. The last iteration of the loop, will cause the post decrement to leave loop in a poorly defined state (it will have wrapped), but there would be no access to the variable once it occured.

    IMHO a on the approach, but I can't go as far as saying it is "wrong" (unless of course I am missing something.
    I can see how it works, but his comment that the OPs loop was "completely wrong" was incorrect. What he offered instead, while it appears it would work, is certainly not the normal way of doing it and not immediately intuitive. The only thing "completely wrong" in the OP's code is his decision to use an unsigned counter.

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by Hermit
    Agreed that it's odd. If I must write a loop that breaks form like that, I tend to prefer writing it as a while-loop. I don't think anyone should have to take a second look at a for-loop to see what it does; they should be used for readability's sake, not for brevity.
    On the other hand, conveniently restricting the lifetime of the loop index to the loop with a for loop makes sense (consider TheCPUWizard's observation that "there would be no access to the variable once it occured").
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  10. #10
    Join Date
    Aug 2005
    Location
    LI, NY
    Posts
    576

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by laserlight View Post
    On the other hand, conveniently restricting the lifetime of the loop index to the loop with a for loop makes sense (consider TheCPUWizard's observation that "there would be no access to the variable once it occured").
    A good point. Certainly one could limit the variable's scope with an extra pair of curly braces, but that would be a bit on the ugly side, and not something I can honestly say that I do. I had read TheCPUWizard's statement differently, by the way, thinking he was noting merely that the variable never contained an unexpected value within the scope of the loop.
    - Alon

  11. #11
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Size_t Weird Bug within Loop

    I prefer to limit the counter scope.

    copy(obj.rbegin(), obj.rend(), ostream_iterator<string>(cout, "\n"));
    Nice approach. Never think before.

    The last iteration of the loop, will cause the post decrement to leave loop in a poorly defined state (it will have wrapped), but there would be no access to the variable once it occured.
    Why last iteration will be no access to the variable once invalid state occurred to the counter variable ?
    Code:
    size_t loop;
    for (loop = obj.size();loop--;)
    {
    	cout << obj[loop] << "\n";
    }
    
    loop = 0;
    The only thing "completely wrong" in the OP's code is his decision to use an unsigned counter.
    Since the MF of size function return unsigned int, therefore i just use size_t to wipe out the warning. Any good approach ?

    Thanks.
    Thanks for your help.

  12. #12
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by PredicateNormative View Post
    Because your decrement loop is completely wrong. Try

    Code:
    for (size_t loop = obj.size(); loop--; )
    {
     ...
    }
    Hello PredicateNormative,
    How are you?

    that code is really a good case study for me.
    and I'd like to know if what I found out is correct or incorrect.
    the code works because decrement operator itself returns
    a new value to be checked as a conditional statement,
    and keeps on going till the value becomes to a number which can be converted to bool,
    thus, stopping if the value is zero(false)
    No?
    Last edited by potatoCode; January 13th, 2009 at 12:13 AM.

  13. #13
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by Peter_APIIT
    Why last iteration will be no access to the variable once invalid state occurred to the counter variable ?
    The variable would be out of scope so it cannot be accessed. Despite stating that you "prefer to limit the counter scope", your new example does not do that, hence there will be access to the variable after the loop.

    Quote Originally Posted by Peter_APIIT
    Since the MF of size function return unsigned int, therefore i just use size_t to wipe out the warning. Any good approach ?
    As I stated, I think reverse iterators are an appropriate solution here. If you really want to use an index, I suppose you could explicitly cast it to int or long.

    Quote Originally Posted by potatoCode
    that code is really a good case study for me.
    and I'd like to know if what I found out is correct or incorrect.
    the code works because decrement operator itself returns
    a new value to be checked as a conditional statement,
    and keeps on going till the value becomes to a number which can be converted to bool,
    thus, stopping if the value is zero(false)
    No?
    That is part of the idea, but you should consider why post-decrement is correct but pre-decrement is not.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  14. #14
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Size_t Weird Bug within Loop

    I have found your descussions about my loop curiously interesting.

    I came across it when I was running performance tests on a compiler that I had to use a couple of years ago. We were struggling to get the required performance out of the application, and on that compiler, I found that decrement loops were faster than increment loops, and that particular decrement loop was the fastest of the lot (though it may not be on other compilers). Because it requires less key strokes, out of laziness, I just got use to using it to the point that I've got so familiar with it, that I forget that it is not a form that people will recognise straight away. I guess that is why I found the responses to it so interesting. I knew it was an uncommon form, but I didn't know it was that uncommon. Had I have realised, I would have used a more well known form - I didn't mean to throw an odd ball in there.

    The loop is to my knowledge completely correct and valid. That said, I am a believer that in the phrase "Programs must be written for people to read, and only incidentally for machines to execute." and from that point, it would be better for me to use well known form. Besides, my initial reason for using the loop (optimisation on a specific compiler), is not a good reason to use that form for everything.

  15. #15
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Size_t Weird Bug within Loop

    Quote Originally Posted by potatoCode View Post
    Hello PredicateNormative,
    How are you?

    that code is really a good case study for me.
    and I'd like to know if what I found out is correct or incorrect.
    the code works because decrement operator itself returns
    a new value to be checked as a conditional statement,
    and keeps on going till the value becomes to a number which can be converted to bool,
    thus, stopping if the value is zero(false)
    No?
    That's pretty much the idea, any non-zero value will evaluate to 'true' whereas zero will evaluate to 'false'. This form of loop effectively removes an expression to be evaluated from each loop cycle. That said, compilers are pretty clever, and might make a better optimisation of a well known loop form. So, although I stand by the correctness of the implementation, I do not claim that this form is good for performance, but if nothing else, it does save on key strokes.
    Last edited by PredicateNormative; January 13th, 2009 at 05:49 AM.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured