do {…} while(false)

前端 未结 25 2301
小鲜肉
小鲜肉 2020-11-28 03:29

I was looking at some code by an individual and noticed he seems to have a pattern in his functions:

 function()
{
 

        
相关标签:
25条回答
  • 2020-11-28 03:57

    The break as goto is probably the answer, but I will put forward one other idea.

    Maybe he wanted to have a locally defined variables and used this construct to get a new scope.

    Remember while recent C++ allows for {...} anywhere, this was not always the case.

    0 讨论(0)
  • 2020-11-28 03:58

    You can break out of do{...}while(false).

    0 讨论(0)
  • 2020-11-28 03:59

    I've seen code like that so you can use break as a goto of sorts.

    0 讨论(0)
  • 2020-11-28 04:00

    A lot of people point out that it's often used with break as an awkward way of writing "goto". That's probably true if it's written directly in the function.

    In a macro, OTOH, do { something; } while (false) is a convenient way to FORCE a semicolon after the macro invocation, absolutely no other token is allowed to follow.

    And another possibility is that there either once was a loop there or iteration is anticipated to be added in the future (e.g. in test-driven development, iteration wasn't needed to pass the tests, but logically it would make sense to loop there if the function needed to be somewhat more general than currently required)

    0 讨论(0)
  • 2020-11-28 04:00

    Many answerers gave the reason for do{(...)break;}while(false). I would like to complement the picture by yet another real-life example.

    In the following code I had to set enumerator operation based on the address pointed to by data pointer. Because a switch-case can be used only on scalar types first I did it inefficiently this way

    if (data == &array[o1])
        operation = O1;
    else if (data == &array[o2])
        operation = O2;
    else if (data == &array[on])
        operation = ON;
    
    Log("operation:",operation);
    

    But since Log() and the rest of code repeats for any chosen value of operation I was wandering how to skip the rest of comparisons when the address has been already discovered. And this is where do{(...)break;}while(false) comes in handy.

    do {
        if (data == &array[o1]) {
            operation = O1;
            break;
        }
        if (data == &array[o2]) {
            operation = O2;
            break;
        }
        if (data == &array[on]) {
            operation = ON;
            break;
        }
    } while (false);
    
    Log("operation:",operation);
    

    One may wonder why he couldn't do the same with break in an if statement, like:

    if (data == &array[o1])
    {
        operation = O1;
        break;
    }
    else if (...)
    

    break interacts solely with the closest enclosing loop or switch, whether it be a for, while or do .. while type, so unfortunately that won't work.

    0 讨论(0)
  • 2020-11-28 04:00

    I agree with most posters about the usage as a thinly disguised goto. Macros have also been mentioned as a potential motivation for writing code in the style.

    I have also seen this construct used in mixed C/C++ environments as a poor man's exception. The "do {} while(false)" with a "break" can be used to skip to the end of the code block should something that would normally warrant an exception be encountered in the loop.

    I have also sen this construct used in shops where the "single return per function" ideology is enforced. Again, this is in lieu of an explicit "goto" - but the motivation is to avoid multiple return points, not to "skip over" code and continue actual execution within that function.

    0 讨论(0)
提交回复
热议问题