DEV Community

Ali Sherief
Ali Sherief

Posted on

Testing less variables with do-while

You may be familiar with the do-while statement, which is:

do {
  /* something */
} while (/* condition */)
Enter fullscreen mode Exit fullscreen mode

Today while reading through the PHP manual, I found an interesting use for this statement. Basically if you're testing for a bunch of stuff present that doesn't make sense to test for unless something else is already present, you can test less conditionals which will make your code faster (especially if it's in a compute-intensive loop like draw() for example), and maybe eliminate some variables from your code.

Suppose you have a button class of a widget library like nanogui, and it has a draw() function that looks something like this C++:

// ...
if (!this->m_hidden && this->m_text != NULL)
  draw(some_canvas, this->m_text);
if (!this->m_hidden && this->m_icon != NULL)
  draw(some_canvas, this->m_icon);
// ...

Enter fullscreen mode Exit fullscreen mode

The real draw() function is much more complicated than this, but if you're curious you can check it out here. I adapted this code for readability, severely condensed it and changed its semantics a little for the purpose of this post.

We can replace the above code with:

// ...
do {
  if (this->m_hidden)
    break;

  if (this->m_text != NULL)
    draw(some_canvas, this->m_text);
  if (this->m_icon != NULL)
    draw(some_canvas, this->m_icon);
}
while (false)
// ...

Enter fullscreen mode Exit fullscreen mode

This code will break if the button is hidden. When a do-while loop has (false) as its condition, it will only run once. That's why it works.

In my opinion, It's better than using a goto statement, which disrupts control flow in case you ever want to prepare a control flow graph of this code.

So why does this have the #php tag? Because as it turns out, PHP has a do-while statement to, is it was inspired by C and C++. In PHP I could write the above code as:

// ...
do {
  if ($this->m_hidden)
    break;

  if ($this->m_text != NULL)
    draw(some_canvas, $this->m_text);
  if ($this->m_icon != NULL)
    draw(some_canvas, $this->m_icon);
}
while (false);
// ...

Enter fullscreen mode Exit fullscreen mode

Hopefully, this gives you one more thing to do with the uncommon do-while statement.

Top comments (0)