Consider:
int fun(int x)
{
do
{
if (x != 0)
break;
if (x != 1)
break;
if (x != -1)
break;
return x;
}
while (0);
return x * x * x;
}
unittest
{
fun(0);
fun(1);
fun(2);
}
The do/while(0); idiom is a trick used to avoid goto or additional state variables. It simply allows code to jump to a common point by using "break". The coverage analyzer marks the line with "while (0);" as uncovered, although that is an useless tidbit.
Comment #1 by hsteoh — 2016-07-01T17:31:11Z
So what's the problem here?
Comment #2 by hsteoh — 2016-07-01T17:35:37Z
Nevermind, I get it now. Sorry for the noise.
Comment #3 by andrei — 2016-07-01T17:48:43Z
For clarity, I'll paste the code (fixed to do something useful, i.e. compute the cube of an int) and the listing:
int cube(int x)
{
do
{
if (x == 0)
break;
if (x == 1)
break;
if (x == -1)
break;
return x * x * x;
}
while (0);
return x;
}
unittest
{
cube(0);
cube(1);
cube(-1);
cube(2);
}
=================================
|int cube(int x)
|{
| do
| {
4| if (x == 0)
1| break;
3| if (x == 1)
1| break;
2| if (x == -1)
1| break;
1| return x * x * x;
| }
0000000| while (0);
3| return x;
|}
|
|unittest
|{
1| cube(0);
1| cube(1);
1| cube(-1);
1| cube(2);
|}
Comment #4 by schveiguy — 2016-07-01T18:03:14Z
I don't see why while(true) is any worse.
Essentially:
while(true)
{
...
break;
}
Is the same as the do...while(0)
Comment #5 by andrei — 2016-07-01T18:12:29Z
(In reply to Steven Schveighoffer from comment #4)
> I don't see why while(true) is any worse.
>
> Essentially:
>
> while(true)
> {
> ...
> break;
> }
>
> Is the same as the do...while(0)
Yah, switch is also fine:
switch (0)
{
default:
....
}
It just seems to me do/while(0) is the clearest, most obvious, and the least bug-prone.
Comment #6 by jbc.engelen — 2016-07-01T18:13:17Z
> The coverage analyzer marks the line with "while (0);" as uncovered, although that is an useless tidbit.
I don't think it is useless. In the OP example, while(0) is uncovered because there is never a "fallthrough exit" of that scope. Consider something like this where coverage of while(0) is useful.
int fun(int x)
{
do
{
if (x != 0)
break;
if (x != 1)
break;
if (x != -1)
break;
mightThrow(x);
}
while (0);
return x * x * x;
}
Comment #7 by andrei — 2016-07-01T18:17:58Z
(In reply to Johan Engelen from comment #6)
> > The coverage analyzer marks the line with "while (0);" as uncovered, although that is an useless tidbit.
>
> I don't think it is useless. In the OP example, while(0) is uncovered
> because there is never a "fallthrough exit" of that scope. Consider
> something like this where coverage of while(0) is useful.
>
> int fun(int x)
> {
> do
> {
> if (x != 0)
> break;
> if (x != 1)
> break;
> if (x != -1)
> break;
> mightThrow(x);
> }
> while (0);
> return x * x * x;
> }
In this case I agree coverage should be as usual. The presence of "return" changes things.
Comment #8 by robert.schadek — 2024-12-13T18:48:49Z