On Saturday, 2 July 2016 at 07:04:28 UTC, Patrick Schluter wrote:
On Friday, 1 July 2016 at 20:30:30 UTC, Steven Schveighoffer wrote:
On 7/1/16 4:08 PM, Andrei Alexandrescu wrote:
On 7/1/16 2:46 PM, Steven Schveighoffer wrote:
On 7/1/16 2:15 PM, Andrei Alexandrescu wrote:
On 7/1/16 2:05 PM, Chris wrote:
On Friday, 1 July 2016 at 16:30:41 UTC, Andrei Alexandrescu wrote:
https://issues.dlang.org/show_bug.cgi?id=16224 -- Andrei

I fail to see why it should not mark it as uncovered in the `cube` example. After all the statement is never covered, because `do`
executes
before the condition in `while` is checked. Unless you mean it
should be
optimized away by the compiler, which in turn has nothing to do with
-cov.

Yah it's a bit subtle. That line is in fact pure punctuation, so even though there's no flow through it that's totally fine (as much as you wouldn't expect a line with a "}" to show no coverage). -- Andrei

Suppose one wants to check if you've covered all cases inside the while loop (with breaks or returns). Then, one would WANT to see 0 coverage
there (non-zero coverage would mean an error in logic).

To remove that feedback would mess up someone else's use case.

This argument is phony. Unconvinced. -- Andrei

I don't use while(0), so I have to invent a hypothetical use case. It's not phony. I could just as easily say that your coding style is illegitimate, and you should use while(true) instead (and thereby get 100% coverage analysis). But I'm not saying that.

There is a legitimate difference between breaking out of the while loop using breaks, and breaking out using the while(0) condition. Why do you want coverage analysis to ignore that difference? Why would someone else's use case that relies on executing or not executing while(0) be invalid?

-Steve

The do {} while(0) "trick" is generally used in C as a poor mans scope(exit) construct without using goto. It is to have one point where the resources used by a function can be freed without duplicating the code everywhere, especially if the function has multiple return points. So in practice it is only "useful" on complex functions with acquisition of resources (memory, files etc) and several exit points (error variants). These kind of functions already have difficult execution flows and adding a level of obfuscation on top of it is not the right solution. Using a goto, while not being the best solution, has at least the merrit of providing a searchable and meaningfull label (goto error or goto finally or goto cleanup are obvious, break not so much) to find the exit. With break it's a little bit more difficult. Add loops and switch's to the equation and you're in for a very confusing debugging session.

Sorry for answering my own comments but the do while(0) code at the link is already a good example of why that construct is bad. To discover what it does, one has to try every possible way in its head, see that it uses an inverted logic (i.e. a double negation) if my parameter isn't a specific value don't do what is close by.

    do
    {
        if (x != 0)
            break;
        if (x != 1)
            break;
        if (x != -1)
            break;
        return x;
    }
    while (0);
    return x * x * x;

is really a lot of lines to write

    if (x == 0 || x == 1 || x == -1)
        return x*x*x;
    else
        return x;

or

    return (x == 0 || x == 1 || x == -1) ? x*x*x : x;


Sorry to still insist on that side show, but it is this inverted logic that is worst part of this construct, making it really, really difficult to analyze in practice.

Reply via email to