Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Evil for loop

Evil for loop

Scheduled Pinned Locked Moved Clever Code
12 Posts 9 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Alois Kraus

    I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

    R Offline
    R Offline
    Rob Graham
    wrote on last edited by
    #2

    NEVER refactor without unit tests...

    A 1 Reply Last reply
    0
    • A Alois Kraus

      I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

      P Offline
      P Offline
      PJ Arends
      wrote on last edited by
      #3

      C4267 is one of those 64bit compatability warnings. size_t is an unsigned int on Win32 but it is an unsigned __int64 on Win64. It used to be that sizeof(int) was OS dependant (2 bytes on Win16, 4 bytes on Win32) but from now on sizeof(int) is fixed at 4 bytes and sizeof(size_t) is variable depending on the OS. Now many CRT functions that used to work with ints now work with size_ts. This stupid change by MS is sure to break a lot of code when it is ported to Win64.


      You may be right I may be crazy -- Billy Joel -- Within you lies the power for good - Use it!

      1 Reply Last reply
      0
      • A Alois Kraus

        I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

        N Offline
        N Offline
        Nemanja Trifunovic
        wrote on last edited by
        #4

        This is one of the reasons I prefer to use a reverse iterator in these "reverse" loops.


        Programming Blog utf8-cpp

        1 Reply Last reply
        0
        • R Rob Graham

          NEVER refactor without unit tests...

          A Offline
          A Offline
          Alois Kraus
          wrote on last edited by
          #5

          I agree. But I must also add: NEVER refactor when not ALL Unit Tests are green. Failing to do so will get you into the bad habit that some test are ok to fail and you miss the new important failed test case.

          1 Reply Last reply
          0
          • A Alois Kraus

            I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

            M Offline
            M Offline
            Michael Dunn
            wrote on last edited by
            #6

            I would've expected a compiler warning there about testing an unsigned variable to be >= 0.

            --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ

            I 1 Reply Last reply
            0
            • A Alois Kraus

              I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

              Z Offline
              Z Offline
              Zac Howland
              wrote on last edited by
              #7

              More importantly, what was the loop actually doing? (I'm assuming you simplified the code for display purposes here). The reason being ... a custom loop may not have been needed at all.

              If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

              A 1 Reply Last reply
              0
              • Z Zac Howland

                More importantly, what was the loop actually doing? (I'm assuming you simplified the code for display purposes here). The reason being ... a custom loop may not have been needed at all.

                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                A Offline
                A Offline
                Alois Kraus
                wrote on last edited by
                #8

                You are right that the code posted here was simplified. I have posted it to demonstrate this specific problem. The loop was needed but this variable hoisting optimization did ruin my day. Yours, Alois Kraus

                1 Reply Last reply
                0
                • M Michael Dunn

                  I would've expected a compiler warning there about testing an unsigned variable to be >= 0.

                  --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ

                  I Offline
                  I Offline
                  ITGFanatic
                  wrote on last edited by
                  #9

                  That's the reason the change from int to size_t broke the code, right? By testing for when an unsigned variable becomes negative, it becomes stuck in an infinite loop. I don't see any other plausible reason for such a simple change to break code. Besides that, you shouldn't have to do reverse iteration. Wouldn't the compiler figure out that it's more efficient to iterate in reverse, and automagically add the appropriate code? I'm recalling a quote by some Knuth guy :) about premature optimization and the root of all evil... I mean, if they're going to the trouble to reverse iterate, why not cache string.length() into an int? One might think that repeatedly calling string.length() is going to be detrimental to performance...

                  P 1 Reply Last reply
                  0
                  • A Alois Kraus

                    I did some refactoring of some older code and came across this snippet: std::string str("This is a test str"); for(int i=str.length()-1;i>=0;i--) { printf("Examining char %d",i); } The compiler complained about this with a warning: warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data Being a fan of zero compiler warnings I did give him what he wanted and changed the type of i from int to size_t. Ok it compiles now without any warnings but this change broke many applications during runtime. I was the bad guy of the week because this change was made in a low level library.

                    W Offline
                    W Offline
                    willbin
                    wrote on last edited by
                    #10

                    str.length() returns an unsigned int.(in MSCRT) so, it's unreliable when you do subtration on it. you should do like below: for (size_t i = 0; i < str.length(); i ++) { printf("Examining char %d",str.length() -i); }

                    //////////////////////////////

                    G

                    P 1 Reply Last reply
                    0
                    • W willbin

                      str.length() returns an unsigned int.(in MSCRT) so, it's unreliable when you do subtration on it. you should do like below: for (size_t i = 0; i < str.length(); i ++) { printf("Examining char %d",str.length() -i); }

                      //////////////////////////////

                      G

                      P Offline
                      P Offline
                      PIEBALDconsult
                      wrote on last edited by
                      #11

                      willbin wrote:

                      for (size_t i = 0; i < str.length(); i ++) { printf("Examining char %d",str.length() -i); }

                      That's another version that should cache the length... it uses the (unchanging) value _twice_ per iteration.

                      1 Reply Last reply
                      0
                      • I ITGFanatic

                        That's the reason the change from int to size_t broke the code, right? By testing for when an unsigned variable becomes negative, it becomes stuck in an infinite loop. I don't see any other plausible reason for such a simple change to break code. Besides that, you shouldn't have to do reverse iteration. Wouldn't the compiler figure out that it's more efficient to iterate in reverse, and automagically add the appropriate code? I'm recalling a quote by some Knuth guy :) about premature optimization and the root of all evil... I mean, if they're going to the trouble to reverse iterate, why not cache string.length() into an int? One might think that repeatedly calling string.length() is going to be detrimental to performance...

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #12

                        ITGFanatic wrote:

                        By testing for when an unsigned variable becomes negative, it becomes stuck in an infinite loop. I don't see any other plausible reason for such a simple change to break code.

                        Accessing memory beyond that which was allocated for the string.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups