Bug 16224 – -cov marks the last line of do/while(0); as uncovered

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-07-01T16:30:08Z
Last change time
2024-12-13T18:48:49Z
Assigned to
No Owner
Creator
Andrei Alexandrescu
Moved to GitHub: dmd#17764 →

Comments

Comment #0 by andrei — 2016-07-01T16:30:08Z
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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17764 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB