• (2 Pages)
  • +
  • 1
  • 2

do {} while(0); Rate Topic: ***-- 2 Votes

#1 sparkart  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 113
  • View blog
  • Posts: 688
  • Joined: 16-February 09

Posted 17 August 2011 - 11:14 PM

This is going to be a very brief tutorial, but hopefully it is still useful. The reason that I am writing this tutorial is because I have recently seen code like this and this is the first time I've seen it. I know that someone might have some questions as to why this would be useful.

Let's start off with some structure:
do
{
  // Insert code here.
} while(0);




You should already be familiar with do { /*insert code*/ } while(/*condition*/); but if not, I'll give you a brief explanation. Basically, the code inside the body of the do statement will be executed as long as the condition of the while statement is true.
do
{
  x++;
} while (x < 100);


So, this loop will increment x by 1 as long as x is smaller than 100.

do while loops are similar to while loops. The difference between the two is that the condition is evaluated first for a while loop. On the other hand, the condition is evaluated last for the do loop. What this means is that code in the body of a do statement will execute atleast once. Code in the body of a while statement can potentially never execute.


Now that we are familiar with the do while loop, let's get back to talking about do { } while(0);

After the previous explanation of a do while loop, you notice that do {} while(0); looks similar to a piece of code that doesn't have it at all:
do
{
     // Insert code here.
} while(0);



Now, at first, this seems pretty useless, why don't we just refactor the code to the following, which is exactly the same:
// Insert code here.




Well there are two reasons that I know of, one dealing with macros, the other dealing with being able to break out of code which is quite common for initializing type of code.

Here is an example without the do while loop:
// Failure will return a null(0) value.
p = CreateNewObject();

if (p != 0)
{
  o = CreateDifferentObject();
  if (o != 0)  
  {
    //...
  }
  else
  {
    //...
  }
  //...
}
else
{
  //...
}


With the do while loop, you can break out of the code on failure:
do
{
  // Failure with return a null(0) value.
  p = CreateNewObject();
  if (p == 0) break;

  o = CreateDifferentObject();
  if (o == 0) break;

  //...
} while(0);



That's all there is to it. I know that it was pretty brief, but I felt like I really had to share this information with the community. Hopefully you found this helpful.

Is This A Good Question/Topic? 3
  • +

Replies To: do {} while(0);

#2 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Posted 18 August 2011 - 03:53 AM

Do you think that there is any benefit over using do { /* ... */ break; /* ... */ } while(0); than a simple void function that you could return from?

You could even inline the function to get the same effect, I guess. Just wondering if there would be any benefit for this really.
Was This Post Helpful? 2
  • +
  • -

#3 anonymouscodder  Icon User is offline

  • member icon

Reputation: 126
  • View blog
  • Posts: 710
  • Joined: 01-January 10

Posted 18 August 2011 - 06:37 AM

Nice trick, but I consider this bad style.

If the purpose is to just 'get out' from the specific scope why not instead make a void function with return statements?
Was This Post Helpful? 0
  • +
  • -

#4 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 1985
  • View blog
  • Posts: 4,119
  • Joined: 11-December 07

Posted 18 August 2011 - 07:03 AM

Could be a useful hack in Java where there is no goto statement. But in C++ you can use goto. If you're going to put explicit jumps in your code, you might as well be honest about it. Using loops doesn't make it any less of a "goto" and could confuse other developers.
Was This Post Helpful? 1
  • +
  • -

#5 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Posted 18 August 2011 - 07:07 AM

View Postcfoley, on 18 August 2011 - 03:03 PM, said:

Could be a useful hack in Java where there is no goto statement. But in C++ you can use goto. If you're going to put explicit jumps in your code, you might as well be honest about it. Using loops doesn't make it any less of a "goto" and could confuse other developers.

Why would you use goto in this instance?
Was This Post Helpful? 0
  • +
  • -

#6 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 1985
  • View blog
  • Posts: 4,119
  • Joined: 11-December 07

Posted 18 August 2011 - 07:35 AM

Perhaps I've misunderstood but I think your example is the same as this:


  p = CreateNewObject();
  if (p == 0) goto getOut;

  o = CreateDifferentObject();
  if (o == 0) goto getOut;

  //...
  getOut:


Was This Post Helpful? 0
  • +
  • -

#7 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4479
  • View blog
  • Posts: 7,801
  • Joined: 08-June 10

Posted 18 August 2011 - 01:17 PM

His point was that the better way to do this is to wrap it in a function:

void doSomething(){
  p = CreateNewObject();
  if (p == 0) return;

  o = CreateDifferentObject();
  if (o == 0) return;

  //...etc...
}


Much better option, IMO, than resorting to goto or a single-iteration loop.

This post has been edited by Curtis Rutland: 18 August 2011 - 01:18 PM

Was This Post Helpful? 0
  • +
  • -

#8 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 1985
  • View blog
  • Posts: 4,119
  • Joined: 11-December 07

Posted 18 August 2011 - 03:48 PM

If that was a reply to me Curtis, I wouldn't dispute it! I'm really not a fan of gotos. I just think they are better than single iteration loops.
Was This Post Helpful? 0
  • +
  • -

#9 sparkart  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 113
  • View blog
  • Posts: 688
  • Joined: 16-February 09

Posted 18 August 2011 - 05:45 PM

You guys may be right, but I thought that maybe I should share this with the community, particularly the newer people in case they ever run into this.

I just recently seen this piece of code while working with Cocos2d-x and you guys are probably right about the fact that this may confuse programmers. But that's essentially why I decided to write about it.

I know for sure that when I saw this piece of code I thought to myself, "what was the point of that".

I don't think that programming is all about writing code, but it is also about working with other people's code.

This post has been edited by sparkart: 18 August 2011 - 05:47 PM

Was This Post Helpful? 0
  • +
  • -

#10 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3101
  • View blog
  • Posts: 19,141
  • Joined: 14-September 07

Posted 18 August 2011 - 05:49 PM

I've only ever seen do while(false); in macros.
Was This Post Helpful? 0
  • +
  • -

#11 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4479
  • View blog
  • Posts: 7,801
  • Joined: 08-June 10

Posted 18 August 2011 - 05:55 PM

Can you explain why they'd be useful in macros? I'm not particularly well versed in C++ macros. I can see why some would think this is a neat trick, but I'd never use it. It's not that it's confusing, it's more of using a construct for something it's really not intended for. I'd actually like to see how compilers would treat this; would they optimize it out?
Was This Post Helpful? 0
  • +
  • -

#12 UziTech  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 64
  • Joined: 26-October 10

Posted 18 August 2011 - 07:53 PM

The if else statement that it relates to is wrong. The actual statement would be

p = createnewobject();
if(p != 0)
{
     o = createdifferentobject();
     if(o != 0)
     {
          //...
     }
}


Which would be the correct way to do the same thing. Creating a function when you don't need to is not a good thing cause it takes more time to call the function.

This post has been edited by NickDMax: 23 August 2011 - 09:21 AM
Reason for edit:: added code tags: [code]...paste code here...[/code]

Was This Post Helpful? 0
  • +
  • -

#13 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4479
  • View blog
  • Posts: 7,801
  • Joined: 08-June 10

Posted 18 August 2011 - 08:16 PM

How much more time? This is an honest question. If it's just a matter of a few more instructions, then I think it's vastly worth it to create more organized code. Premature optimization is the root of all programming evil. If this goes more than a few layers deep, you'd be creating an unmaintainable mess of code, where as a method with returns is all one level, easy to add and take away from. If you're programming for an environment where you can't spare a single processor cycle or stack call, sure, optimize that away. But otherwise, I say go for the most maintainable code.
Was This Post Helpful? 0
  • +
  • -

#14 UziTech  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 64
  • Joined: 26-October 10

Posted 19 August 2011 - 07:20 AM

View PostCurtis Rutland, on 18 August 2011 - 09:16 PM, said:

How much more time? This is an honest question. If it's just a matter of a few more instructions, then I think it's vastly worth it to create more organized code. Premature optimization is the root of all programming evil. If this goes more than a few layers deep, you'd be creating an unmaintainable mess of code, where as a method with returns is all one level, easy to add and take away from. If you're programming for an environment where you can't spare a single processor cycle or stack call, sure, optimize that away. But otherwise, I say go for the most maintainable code.


Very true. The amount of time it is going to take to call the function is miniscule but so is the amount of time figuring out a goto yet people still gripe about using them. My point was each of these ways will get the exact same thing done but if you want it optimized the if statement is the way to go. Personally I would make it a function for reusability
Was This Post Helpful? 0
  • +
  • -

#15 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Posted 19 August 2011 - 07:23 AM

I'd much rather throw an exception in all these cases. If you don't catch it, the debugger will, (assuming of course that you use one) and it will show you exactly what happened where.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2