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. General Programming
  3. C / C++ / MFC
  4. Why have they done this?

Why have they done this?

Scheduled Pinned Locked Moved C / C++ / MFC
questionlearning
9 Posts 6 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.
  • R Offline
    R Offline
    RChin
    wrote on last edited by
    #1

    So I'm going through the source code for the Log4CPlus logging library and found this snippet:#define LOG4CPLUS_DEBUG(logger, logEvent) \ do { \ if(logger.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) { \ log4cplus::tostringstream _log4cplus_buf; \ _log4cplus_buf << logEvent; \ logger.forcedLog(log4cplus::DEBUG_LOG_LEVEL, _log4cplus_buf.str(), __FILE__, __LINE__); \ } \ } while(0);
    This of course logs a given string to the active logging class. The question is why have they wrapped all that in a do-while loop? If you look at the loop, it will only be called once (while(0)). Is this some kind of preventitive measure to ensure that the compiler or optimiser does not strip the macro code out?


    I Dream of Absolute Zero

    V T 2 Replies Last reply
    0
    • R RChin

      So I'm going through the source code for the Log4CPlus logging library and found this snippet:#define LOG4CPLUS_DEBUG(logger, logEvent) \ do { \ if(logger.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) { \ log4cplus::tostringstream _log4cplus_buf; \ _log4cplus_buf << logEvent; \ logger.forcedLog(log4cplus::DEBUG_LOG_LEVEL, _log4cplus_buf.str(), __FILE__, __LINE__); \ } \ } while(0);
      This of course logs a given string to the active logging class. The question is why have they wrapped all that in a do-while loop? If you look at the loop, it will only be called once (while(0)). Is this some kind of preventitive measure to ensure that the compiler or optimiser does not strip the macro code out?


      I Dream of Absolute Zero

      V Offline
      V Offline
      Viorel
      wrote on last edited by
      #2

      For an answer, please see: http://c-faq.com/cpp/multistmt.html[^]

      R 1 Reply Last reply
      0
      • V Viorel

        For an answer, please see: http://c-faq.com/cpp/multistmt.html[^]

        R Offline
        R Offline
        RChin
        wrote on last edited by
        #3

        Ahhh! Thanks.


        I Dream of Absolute Zero

        Z 1 Reply Last reply
        0
        • R RChin

          So I'm going through the source code for the Log4CPlus logging library and found this snippet:#define LOG4CPLUS_DEBUG(logger, logEvent) \ do { \ if(logger.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) { \ log4cplus::tostringstream _log4cplus_buf; \ _log4cplus_buf << logEvent; \ logger.forcedLog(log4cplus::DEBUG_LOG_LEVEL, _log4cplus_buf.str(), __FILE__, __LINE__); \ } \ } while(0);
          This of course logs a given string to the active logging class. The question is why have they wrapped all that in a do-while loop? If you look at the loop, it will only be called once (while(0)). Is this some kind of preventitive measure to ensure that the compiler or optimiser does not strip the macro code out?


          I Dream of Absolute Zero

          T Offline
          T Offline
          toxcct
          wrote on last edited by
          #4

          because it provides a bloc of code... simply.


          TOXCCT >>> GEII power

          [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

          1 Reply Last reply
          0
          • R RChin

            Ahhh! Thanks.


            I Dream of Absolute Zero

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

            The reason given in that article is actually pretty poor. Yes, it forces the programmer to use a trailing semi-colon, but that isn't necessary (mostly, they do that simply for looks). The real reason for enclosing it in a do-while loop is to prevent naming conflicts. For example, lets say you have the following macro: #define SWAP_INT(a, b) \ int c = a; \ a = b; \ b = c; Now, your code looks something like the following: void main() { int a = 1, b = 2, c = 0; SWAP_INT(a, b); // compiler-error! c is declared multiple times } This creates a hard to find compiler-error that will annoy you (and anyone else trying to use that macro with a variable named 'c'). To prevent this, you could use the scoping operator: #define SWAP_INT(a, b) \ { \ int c = a; \ a = b; \ b = c; \ } However, some older C++ compilers do not treat this correctly (or even handle it at all. Thus, you can create a single loop do-while to handle the scoping: #define SWAP_INT(a, b) \ do { \ int c = a; \ a = b; \ b = c; \ } while (0); The trailing ; is purely optional. If you leave it off, you force the programmer to place it themselves (thus treating it like a function call). Putting it there doesn't hurt anything though. As a side note, declaring it the way they did (as a macro) is poor programming practice. It really should have been declared as a function. If the user passes an int as the "logger", they will get some weird compiler error messages dealing with types and unless they search through the code to find the macro defintion, will have no idea why it is happening. 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 -- modified at 11:53 Thursday 1st June, 2006

            R J 2 Replies Last reply
            0
            • Z Zac Howland

              The reason given in that article is actually pretty poor. Yes, it forces the programmer to use a trailing semi-colon, but that isn't necessary (mostly, they do that simply for looks). The real reason for enclosing it in a do-while loop is to prevent naming conflicts. For example, lets say you have the following macro: #define SWAP_INT(a, b) \ int c = a; \ a = b; \ b = c; Now, your code looks something like the following: void main() { int a = 1, b = 2, c = 0; SWAP_INT(a, b); // compiler-error! c is declared multiple times } This creates a hard to find compiler-error that will annoy you (and anyone else trying to use that macro with a variable named 'c'). To prevent this, you could use the scoping operator: #define SWAP_INT(a, b) \ { \ int c = a; \ a = b; \ b = c; \ } However, some older C++ compilers do not treat this correctly (or even handle it at all. Thus, you can create a single loop do-while to handle the scoping: #define SWAP_INT(a, b) \ do { \ int c = a; \ a = b; \ b = c; \ } while (0); The trailing ; is purely optional. If you leave it off, you force the programmer to place it themselves (thus treating it like a function call). Putting it there doesn't hurt anything though. As a side note, declaring it the way they did (as a macro) is poor programming practice. It really should have been declared as a function. If the user passes an int as the "logger", they will get some weird compiler error messages dealing with types and unless they search through the code to find the macro defintion, will have no idea why it is happening. 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 -- modified at 11:53 Thursday 1st June, 2006

              R Offline
              R Offline
              RChin
              wrote on last edited by
              #6

              Very clearly explained. Thank you. You got my 5.


              I Dream of Absolute Zero

              1 Reply Last reply
              0
              • Z Zac Howland

                The reason given in that article is actually pretty poor. Yes, it forces the programmer to use a trailing semi-colon, but that isn't necessary (mostly, they do that simply for looks). The real reason for enclosing it in a do-while loop is to prevent naming conflicts. For example, lets say you have the following macro: #define SWAP_INT(a, b) \ int c = a; \ a = b; \ b = c; Now, your code looks something like the following: void main() { int a = 1, b = 2, c = 0; SWAP_INT(a, b); // compiler-error! c is declared multiple times } This creates a hard to find compiler-error that will annoy you (and anyone else trying to use that macro with a variable named 'c'). To prevent this, you could use the scoping operator: #define SWAP_INT(a, b) \ { \ int c = a; \ a = b; \ b = c; \ } However, some older C++ compilers do not treat this correctly (or even handle it at all. Thus, you can create a single loop do-while to handle the scoping: #define SWAP_INT(a, b) \ do { \ int c = a; \ a = b; \ b = c; \ } while (0); The trailing ; is purely optional. If you leave it off, you force the programmer to place it themselves (thus treating it like a function call). Putting it there doesn't hurt anything though. As a side note, declaring it the way they did (as a macro) is poor programming practice. It really should have been declared as a function. If the user passes an int as the "logger", they will get some weird compiler error messages dealing with types and unless they search through the code to find the macro defintion, will have no idea why it is happening. 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 -- modified at 11:53 Thursday 1st June, 2006

                J Offline
                J Offline
                James R Twine
                wrote on last edited by
                #7

                An excellent explaination!  However, I will offer one more use of the do/while(0) block.  I have seen it used as a way to provide goto-like functionality without actually using the word goto.    For example, if you needed to jump out of the middle of the block, simply executing a break will take you to the bottom of the block, simulating a goto to a label at the end of the block.    It was a bit confusing the first time I saw code that used the do/while(0) like that... [Edit: Note, I do not do this myself, and would use (and have used) used a goto in place of something like that...]    Peace! -=- James


                If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
                Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
                DeleteFXPFiles & CheckFavorites (Please rate this post!)

                B Z 2 Replies Last reply
                0
                • J James R Twine

                  An excellent explaination!  However, I will offer one more use of the do/while(0) block.  I have seen it used as a way to provide goto-like functionality without actually using the word goto.    For example, if you needed to jump out of the middle of the block, simply executing a break will take you to the bottom of the block, simulating a goto to a label at the end of the block.    It was a bit confusing the first time I saw code that used the do/while(0) like that... [Edit: Note, I do not do this myself, and would use (and have used) used a goto in place of something like that...]    Peace! -=- James


                  If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
                  Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
                  DeleteFXPFiles & CheckFavorites (Please rate this post!)

                  B Offline
                  B Offline
                  Blake Miller
                  wrote on last edited by
                  #8

                  And in situations like that, exactly, I favor the goto - at least I know what is going on logically. The do{ }while(0); crap I really have to think about for a minute - to realize they just did not want to use the goto. People that start writing code immediately are programmers (or hackers), people that ask questions first are Software Engineers - Graham Shanks

                  1 Reply Last reply
                  0
                  • J James R Twine

                    An excellent explaination!  However, I will offer one more use of the do/while(0) block.  I have seen it used as a way to provide goto-like functionality without actually using the word goto.    For example, if you needed to jump out of the middle of the block, simply executing a break will take you to the bottom of the block, simulating a goto to a label at the end of the block.    It was a bit confusing the first time I saw code that used the do/while(0) like that... [Edit: Note, I do not do this myself, and would use (and have used) used a goto in place of something like that...]    Peace! -=- James


                    If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
                    Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
                    DeleteFXPFiles & CheckFavorites (Please rate this post!)

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

                    James R. Twine wrote:

                    An excellent explaination! However, I will offer one more use of the do/while(0) block. I have seen it used as a way to provide goto-like functionality without actually using the word goto. For example, if you needed to jump out of the middle of the block, simply executing a break will take you to the bottom of the block, simulating a goto to a label at the end of the block. It was a bit confusing the first time I saw code that used the do/while(0) like that...

                    People that code like that do so for job-security. You should NEVER do that. If you actually look at the assembly code produced by the compiler when you write a do-while(0) with a break instead of just using goto, you'll notice it is exactly the same as when you do write a goto. Although, your reasoning does offer another good reason for making this a function instead of a macro. Instead of a goto or break, you just return if you get to a state that needs such. Much cleaner, and you won't have someone asking you what the heck you are doing when they have to maintain your code. 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

                    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